AJAX 请求跨域处理
浏览器出于安全考虑,要求的同源是指:
- 协议相同,如http,https为不同协议
- 域名相同,如http://www.example.com 与 http://example.com域名不同
- 端口相同
"同源"的限制范围:
- Cookie,LocalStorage 和 IndexDB 无法读取;
- DOM无法读取;
- AJAX请求失败;
在通常的后端开发工作中,涉及到的跨域问题主要是AJAX跨域请求;
除了由同源服务器代理请求外,可以通过三种方式规避跨域问题:
- JSONP
- WebSocket
- CORS
其中JSONP兼容老式浏览器,操作简单,但只能发送GET请求;
基本思想是网页通过一个<scritp>元素向服务器请求JSON数据,这种做法不收同源政策限制;
服务请收到请求后,将数据放在一个指定名字的回调函数里传回来;
服务构造回调的script作为js代码返回给浏览器执行;
具体参考: https://stackoverflow.com/questions/11694124/tornado-write-a-jsonp-object
WebSocket的跨域参考这篇文章,http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html;
重点要关注的还是CORS(跨资源分享),是AJAX跨域请求的根本解决办法:
在一般的开发任务中,最经常遇到的就是这个了;
CORS请求分为两类,简单请求和非简单请求:
具体流程参考以下两篇文章
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS
http://www.ruanyifeng.com/blog/2016/04/cors.html
同时满足以下两大条件,就是简单请求:
- 请求方法是以下三种之一:
- HEAD
- GET
- POST
- HTTP头信息不超过以下几种字段
- Accept
- Accpet-Language
- Content-Language
- Last-Event-ID
- Content-Type: 只限于
application/x-www-form-urlencoded、multipart/form-data、text/plain
对于简单请求,浏览器直接发出CORS请求,对于复杂请求,浏览器会自行追加一次"预检"请求,方法为options;
针对简单的请求,服务端需要增加的头字段有三个:
Access-Control-Allow-Origin, 该字段是必须的,其值可以为请求中Origin的值;
也可以为*号,表示接受任意域名请求,但不能与Access-Control-Allow-Credentials同时启用;Access-Control-Allow-Credentials, 可选,表示是否允许发送Cookie;Access-Control-Expose-Headers,可选,添加新的头部字段的值;
复杂请求,有较多的字段可用于配置;主要需要配置预检请求;
Demo
最后给一个简单的示例:
场景是这样的,在当前地址为http://a.example.com的页面,
需要向http://b.example.com的URL发送一个跨域请求;
前端需要构造一个CORSmode的跨域请求,而server端需要在返回的响应中添加相应的头部字段;
如果最简单的情况只需要添加Access-Control-Allow-Origin: a.example.com就可以了;
当然这是最简单的情况,如果有更多的需求查阅下上述给出的参考资料应该不难解决;
浙公网安备 33010602011771号