AJAX 请求跨域处理

浏览器出于安全考虑,要求的同源是指:

"同源"的限制范围:

  • 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

同时满足以下两大条件,就是简单请求:

  1. 请求方法是以下三种之一:
    • HEAD
    • GET
    • POST
  2. HTTP头信息不超过以下几种字段
    • Accept
    • Accpet-Language
    • Content-Language
    • Last-Event-ID
    • Content-Type: 只限于application/x-www-form-urlencodedmultipart/form-datatext/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就可以了;

当然这是最简单的情况,如果有更多的需求查阅下上述给出的参考资料应该不难解决;

参考资料


  1. 阮一峰《浏览器同源政策及其规避方法》http://www.ruanyifeng.com/blog/2016/04/same-origin-policy.html
  2. 阮一峰 《跨域资源共享 CORS 详解》 http://www.ruanyifeng.com/blog/2016/04/cors.html
  3. https://stackoverflow.com/questions/11694124/tornado-write-a-jsonp-object
  4. https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS

posted on 2017-06-01 02:01  yabzhang  阅读(186)  评论(0)    收藏  举报

导航