HTTP支持跨域
HTTP网络中的跨域指的是不同的Host之间的通信,IP(域名)+端口就指定一个域;这几天处理了一个跨域的问题,发现有点坑;这里记录下
HTTP服务器支持跨域
默认情况下HTTP服务器通常是不支持跨域的;跨域可能会引入CSRF攻击的风险
Access-Control-Allow-Methods: "GET, POST, OPTIONS"
Access-Control-Allow-Headers: "DNT,Cache-Control,Content-Type,X-Requested-With,User-Agent,Keep-Alive,X-Mx-ReqToken,If-Modified-Since"
Access-Control-Allow-Origin: *
-
Access-Control-Allow-Methods
指的是服务器支持跨域的请求类型 -
Access-Control-Allow-Headers
指的是服务器支持跨域携带的头字段 -
Access-Control-Allow-Origin
指的是服务器允许跨域的域,比如设置为baidu.com
那么仅允许baidu.com
发起对该服务器的跨域,请求的Origin
头字段和该字段符合的情况才允许跨域,可以设置为通配符*
非简单请求的跨域
以上支持的只是简单请求的跨域
什么是简单请求
- 请求类型为GET、POST、HEAD,
- 头字段只允许Accept、Accept-Language、Content-Languate、Content-Type
- Content-Type只允许text/plain、multipart/form-data、application/x-www-form-urlencoded
- 除此之外全是复杂请求
怎么支持复杂请求?
如果需要用到JSON格式、添加自定义头的时候就需要支持复杂请求了
在复杂请求的时候,浏览器会在请求前先发送一个OPTIONS
请求,该请求的作用就是询问服务器对请求方法、请求头的支持情况;
服务器支持OPTIONS
请求,头字段和前述跨域一致,返回200、204即可
跨域怎么携带Cookie
跨域携带Cookie是一件很危险的事,但是实际的编程实践当中还是有可能用到的
前端支持
携带Cookie必须前端和后端配合一起实现才可以
var xhr = new XMLHttpRequest( );
//监听XHR对象的状态改变事件
xhr.onreadystatechange = function() {
if( xhr.readyState===4) {
if(xhr.status===200) {
}
else {
}
}
}
xhr.withCredentials = true; //支持跨域携带Cookie
//打开到服务器的连接
xhr.open(method, uri, true)
//发起请求消息
xhr.send()
后端支持
Access-Control-Allow-Methods: "GET, POST, OPTIONS"
Access-Control-Allow-Headers: "DNT,Cache-Control,Content-Type,X-Requested-With,User-Agent,Keep-Alive,X-Mx-ReqToken,If-Modified-Since"
Access-Control-Allow-Origin: origin
Access-Control-Allow-Credentials: true
-
Access-Control-Allow-Credentials
允许跨域携带Cookie -
Access-Control-Allow-Origin
不再允许指定通配符了,而是必须指定域名
Chrome/IE兼容性问题
在Chrome80
以上的版本的时候SameSite
的默认安全级别比较高,需要给Set-Cookie
的Cookie
添加SameSite=None;
的属性
在ie11
浏览器的默认隐私级别也是无法携带Cookie的,需要添加一个新的头字段P3P: CP=CAO PSA OUR
;如果把隐私级别调低就不需要设置了,但是显然无法要求每个用户这样操作
在ie10
浏览器中的默认配置下是无法跨非法的HTTPS地址的,在ie11
的基础上还必须要求合法证书
在ie9
浏览器中前端AJAX由XDomainRequest实现,必须点击IE浏览器的工具->Internet选项->安全->自定义级别将"爱他"选项中的"通过域访问数据源"选中为"启用"或者"提示"才可以实现,也就是必须每个客户端必须手动修改才可以
网友评论