CORS是W3C标准。全场跨域资源共享(Cross-origin resourse sharing)
她允许浏览器向跨域资源服务器放出XMLHttpRequest请求,克服了AJAX只能同源使用的限制
1,CORS通信是浏览器自动完成的,不需要用户参与。CORS通信和同源的AJAX通信没有差别,代码完全一样,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以通信
Access-Control-Allow-Origin:*
(1) 为什么会有跨域的问题
浏览器安全的基石是:同源策略。什么是同源策略,简言之就是:请求的
协议相同 + 域名相同 + 端口号相同,只有在这三种情况都相同的情况下,才能 被称为同源策略。特别是在前后端分离开发的条件下,几乎跨域是一定会遇到的问题。
(2)CORS请求分成两类:简单请求和非简单请求
只有满足一下两大请求就属于简单请求:
(1)请求方法是以下三种方法之一:Head,get,post
(2) Http的头消息不能超出一下几种字段:
Content-Type:只限于三个值:application/x-www-form-urlencoded,(一般请求默认的方法) multipart/form-data,text/plain
除此之外:凡是不满足的都是非简单请求
(3)CORS请求流程
对于简单请求,浏览器直接发出CORS请求,并且在请求当前头信息中添加一个origin字段。origin其实就是(协议+域名+端口号),服务器根据这个值决定是否同意这次请求。
对于非简单请求,比如请求方法是put或者delete,或者Content-Type字段类型是application/json,,在正是请求之前会,服务器发现你是一个非简单请求,就会自动发出一个预检请求,预检请求的方法是OPTIONS,表示咨询。如果如服务器对预检请求的结果是允许跨域请求,就会第二次发出请求跨域请求。一旦服务器通过了预检请求,以后的每一次CORS请求都是简单请求了。
(5)CORS默认请求不会发送Cookie和HTTP认证信息的。如果要把Cookie发送到服务器,需要知道服务器同意:
Access-Control-Allow-Credentials:true
前端需要设置: widthCredentials = true
(4)CORS与JSONP的比较
CORS与JSON的目的相同,但是比JSONP更强大。
JSONP只支持GET请求,CORS支持所有类型的HTTP请求。JSON的优势在与支持老式浏览器,可以向布置CORS的网站请求数据
注意:我们在使用POST方式是,JQuery,Axios等封装的Ajax库,都采用默认的
Content-Type:application/x-www-form-urlencoded,不会触发预请求
举例:处理POST预请求方法
前端发出请求,触发预请求
var data = { name: 'BruceLee', password: '123456' };
$.ajax({
url: "http://localhost:3000",
type: "post",
data: JSON.stringify(data),
contentType: 'application/json;charset=utf-8',
success: function (result) {
console.log(result);
},
error: function (msg) {
console.log(msg);
}
})
服务器端要增加对OPTIONS得请求,比如node.js
const http = require('http');
const server = http.createServer((request, response) => {
if (request.url === '/') {
if (request.method === 'GET') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
response.end("{name: 'BruceLee', password: '123456'}");
}
if (request.method === 'POST') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*'
});
response.end( JSON.stringify({state: true}) );
}
if (request.method === 'OPTIONS') {
response.writeHead(200, {
'Access-Control-Allow-Origin': '*', // 设置 optins 方法允许所有服务器访问
'Access-Control-Allow-Methods': '*', // 允许访问路径 '/' POST等所有方法
'Access-Control-Allow-Headers': 'Content-Type', // 允许类 Content-Type 头部
});
}
}
response.end('false');
});
server.listen(3000, () => {
console.log('The server is running at http://localhost:3000');
});
总结:使用CORS跨域资源共享,是需要分成预请求和非预请求处理的。
(1)非预请求:只需要在服务器端简单的数字:
'Access-Control-Allow-Origin': '*'
(2)预请求,在服务器内,至少需要设置三个响应首部字段:
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': '*',
'Access-Control-Allow-Headers': 'Content-Type',
(3)前端使用Content-Type:application/json的时候,必须注意,这是要发生预请求的,后端需要相对于的处理一下OPTIONS方法