首先我们要先知道什么是同源策略,跨域就是因为同源策略导致的
1.为什么要有同源策略
浏览器设置同源策略只是为了完全性考虑,如果没有同源策略的话,浏览器的cookie可被任意读取,不同域名下可以任意操作DOM元素,ajax任意请求不同域名下的数据,导致信息泄漏
2.什么是同源策略
两个页面的 协议 域名 端口 三同才被称为同源,如果其中有一项不同就会导致跨域
3.同源策略的限制
不能通过ajax请求任意域名下的数据,不能通过脚本操作任意域名下的DOM
话不多说,言归正传
简单请求
只要同时满足以下两大条件,就属于简单请求
条件1:使用请求方法
- GET
- HEAD
- POST
条件2:Content-type值仅限于以下三个之一
- application/x-www-form-urlencoded
- text/plain
- multipart/form-data
简单请求直接在node后台写允许跨域的一句话
var ex = require('express')
var app = ex();
app.use('/',function(req,res){
res.setHeader('Access-Control-Allow-origin','*'); // 允许所有域名跨域
res.send({"name":"秦司令"})
})
app.listen(3000)
当跨域成功后,前端页面的报文请求头属性中会新增一个origin属性,值默认为本地的域名
报文请求头的属性origin非简单请求
不满足以上的两大条件就为非简单请求,发送非简单请求得在前台页面写一个自定义的报文请求头属性content-type
非简单请求的cors请求,是发送请求之后先在服务端 "预检" 一遍,预检发送的请求方法是 OPTIONS ,看看服务端是否允许跨域,假如我们使用PUT请求方法向后台发送请求,属于非简单请求,需要在node后台设置
前台页面
var xhr = new XMLHttpRequest();
xhr.open('PUT','http://localhost:3000',true);
xhr.setRequestHeader('token', 'value');
xhr.send();
xhr.onreadystatechange = function(){
if(xhr.readyState == 4){
if(xhr.status >= 200 && xhr.status <= 300 || xhr.status == 304){
console.log(xhr.responseText)
}
}
}
node后台设置
var ex = require('express');
var app = ex();
app.use('/',function(req,res){
res.setHeader('Access-Control-Allow-Origin','*');
res.setHeader('Access-Control-Allow-Methods','PUT,GET,POST')
res.setHeader('Access-Control-Allow-Headers','token');
res.send({"name":"秦司令"})
})
app.listen(3000)
Access-Control-Allow-Origin
该属性必须得写,是允许那个域名才能跨域,* 所有的域名都能访问,但是如果写*通配符的话,那么cookie都发不过去,必须得指定域名
Access-Control-Allow-Methods
允许那个方法访问我,值可以是字符串分割字段的
Access-Control-Allow-Credentials
该属性可选,它的值是一个布尔值,表示是否允许发送cookie,即cors请求中,不包括cookie,设为true,即表示服务器明确即可,cookie可以包含在请求中,一起发送给服务器
withCredentials
上面说到,cors请求默认不发送cookie和http认证信息,如果要把cookie发送到服务端,一方面服务器要同意,指定Access-Control-Allow-Credentials
res.setHeader('Access-Control-Allow-Credentials',true) // 允许可发送cookie
另一方面,开发者必须在ajax请求中打开withCredentials
var xhr = new XMLHttpRequest()
xhr.withCredentials = true;
否则,即使服务器同意发送cookie,浏览器也不会发送,或者,服务端设置cookie,浏览器端也不会处理,但是,如果省略withCredentials设置,有的浏览器还是会一起发送cookie,这时可以显示关闭withCredentials
网友评论