跳到主要内容

浏览器跨域问题

什么是跨域

在前端中,跨域是指浏览器允许向服务器发送跨域请求,从而可以客服 Ajax 只能同源使用的问题

同源策略

所谓的同源是指协议域名端口相同,即使两个不同的域名指向同一个 ip 地址也是不同源的

URL说明结果
https://www.baidu.com/b.js https://www.baidu.com/a.js协议、域名、端口都相同同源
www.baidu.com:80/a.js www.baidu.com/a.js协议、域名相同,端口不同不同源
http://www.baidu.com/a.js https://www.baidu.com/a.js协议不同不同源
https://doc.baidu.com https://www.baidu.com域名不同不同源

跨域解决方案

JSONP 跨域

使用 script 标签进行跨域请求,但是只支持 get 请求 通过 script 标签引入一个 js 文件,这个 js 文件载入成功后会执行我们在 url 参数中指定的函数,并且会把我们需要的 json 数据作为参数传入

<script>
var script = document.createElement("script");
script.type = "text/javascript";
script.src =
"http://www.example.com/login?user=admin&callback=handleCallback";
document.head.appendChild(script);
function handleCallback(res) {
console.log(res);
}
</script>

CORS 跨域

处理简单的跨域请求,浏览器直接发出 CORS,在头信息中加一个 Origin,Origin 中的就是来自于哪个源(协议+域名+端口) Access-Control-Allow-Origin表示允许来自哪个元的请求,要么是 *,要么是指定的域名 如果是 *,表示所有的域名都可以访问 如果是指定的域名,表示只有指定的域名可以访问 Access-Control-Allow-Credentials表示是否允许发送 cookie 如果是 true,表示允许发送 cookie 如果是 false,表示不允许发送 cookie Access-Control-Expose-Headers表示哪些头信息可以暴露给外部

复杂的请求,比如请求是 PUT 或者是 DELETE,或者 Content-Type 是 application/json,这种请求会先发一个预检请求,预检请求是一个 OPTIONS 请求,如果服务器允许,浏览器才会发出真正的请求 这个请求是用来询问的,询问服务器是否允许这个请求 Access-Control-Request-Method表示请求的方法 Access-Control-Request-Headers表示请求头信息 服务器收到了预检请求之后检查了以上这些字段,确认允许跨源请求之后会做出回应

nodejs 代码

var http = require("http");
var server = http.createServer();
var qs = require("querystring");
server.on("request", function (req, res) {
var postData = "";
//数据块接收
req.addListener("data", function (postDataChunk) {
postData += postDataChunk;
});
//数据接收完毕
req.addListener("end", function () {
postData = qs.parse(postData);
res.writeHead(200, {
"Access-Control-Allow-Origin": "http://localhost:63342",
//允许跨域的域名,*表示所有域名都可以跨域

"Access-Control-Allow-Credentials": "true", //是否允许发送cookie
"Access-Control-Expose-Headers":
"Content-Type,Content-Length,Authorization,Accept,X-Requested-With",
"Access-Control-Allow-Methods": "PUT,POST,GET,DELETE,OPTIONS",
"Access-Control-Allow-Headers":
"Content-Type,Content-Length,Authorization,Accept,X-Requested-With",
});
res.write(JSON.stringify(postData));
res.end();
});
});

后续内容实践完后再来补充 🚧