跨域请求 JSONP & CORS

跨域请求 JSONP & CORS

页面ajax跨域请求会受到浏览器同源策略的限制,不同协议、端口、主机(域名)等情况都会被限制。而在实际项目当中,跨域请求也经常会用到,常用的跨域请求有JSONP、CORS。

JSONP

浏览器对跨域ajax请求作限制,但是允许加载不同域静态文件,如css、js、img等。
如a.com加载b.com静态文件。

<script src="http://b.com/test.js"></script>
<img src="http://b.com/logo.png" alt="" title="" />
<link href="http://b.com/style.css" />

JSONP是利用浏览器的这一特性,将 script的src指向跨域的接口,并传递回调函数,接口返回的数据包含在回调函数的参数(JSON)里。script加载完成后会执行回调函数。

JSONP是JSON width padding 的简写,由回调函数和数据两部分组成。

// 前端代码
<script>
    // 定义回调函数
  function logInfo (data) {
    console.log(data);
  }
</script>
<script src="http://b.com/getUserInfo?callBack=logInfo"></script>
// 后端代码
router.get('/getUserInfo',  function(req, res, next) {
  // 回调函数
  let callBack = req.query.callBack;
  // JSON数据
  let data = {
    userName: '张三',
    age: 25
  };
  res.send(callBack + '(' + JSON.stringify(data) + ')');
});

代码简单实现


/**
 * JSONP跨域请求
 * @param  {String} url      请求地址
 * @param  {Object} params   请求参数
 * @param  {String} callBack 回调函数名
 */
function crossDomain (url, params, callBack) {
  let script;
  let query = '';
  for(k in params){
    query += k + '=' + params[k] + '&';
  };
  script = document.createElement('script');
  script.src = url + '?' + query + '&callBack=' + callBack;
  script.onload = function () {
    // do something
  };
  document.head.appendChild(script);
};

crossDomain('http://b.com/getUserInfo', {id: 1}, 'logInfo');

动态加载script后,浏览器会立即执行返回的js。

logInfo({"userName":"张三","age":25})

CORS

CORS(Cross-Origin Resource Sharing,跨域资源共享),通过自定义HTTP头部让浏览器与服务器进行沟通,判断request或response成功与否。
CORS 需要客户端与服务端同时支持,现在大部分浏览器都支持,早期IE8、IE9需要通过XDomainRequest实现。

客户端请求头设置

HTTP首部字段无须手动设置,在发起请求时自动设置。
跨域请求头部

Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6
Connection:keep-alive
Content-Type:application/x-www-form-urlencoded
Host:www.b.com
Origin:http://www.a.com
Referer:http://www.a.com/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36

同域请求头部

Accept:application/json, text/javascript, */*; q=0.01
Accept-Encoding:gzip, deflate, br
Accept-Language:zh-CN,zh;q=0.8,en;q=0.6
Connection:keep-alive
Content-Type:application/x-www-form-urlencoded
Host:www.b.com
If-None-Match:W/"1d-ObzyCxC5+mC0i89GegH96w"
Referer:http://www.b.com/
User-Agent:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36
X-Requested-With:XMLHttpRequest

跨域请求头部会被设置参数Origin:http://www.a.com,用于服务端判断是否允许跨域。

服务端响应头设置

服务端通过设置响应参数决定是否允许请求。

  • Access-Control-Allow-Origin 允许跨域请求源,如果是公共资源或不需要限制请求源可设置*
  • Access-Control-Allow-Methods 允许请求的方法,多个方法已逗号隔开
  • Access-Control-Allow-Headers 允许请求的头部,多个头部已逗号隔开
  • Access-Control-Max-Age 请求缓存多长时间

以Access-Control-Allow-Origin为例的跨域过程。如果感兴趣,可以查看下COR的实现方式。
imgage

JSONP 与 CORS 区别

JSONP与跨域资源共享(CORS)同样可实现跨域请求,CORS通过设置相应头(请求头无须手动设置),从而避开浏览器的同源策略。

  • JSONP只支持GET请求,而 CORS 支持其他HTTP请求(如POST)
  • JSONP是利用浏览器加载跨域静态文件实现,而CORS是通过XMLHttpRequest(IE8、9通过XDomainRequest)请求实现

参考文献

MDN
JavaScript高级程序设计(第3版)

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值