饥人谷技术博客

JavaScript中的跨域请求策略

2017-08-15  本文已影响0人  饥人谷_Grey高

概念

当一个资源从与该资源本身所在的服务器不同的域或端口请求一个资源时,资源会发起一个跨域 HTTP 请求
出于安全考虑,浏览器会限制从脚本内发起的跨域HTTP请求。例如,XMLHttpRequest
Fetch遵循同源策略。因此,使用 XMLHttpRequestFetch 的Web应用程序只能将HTTP请求发送到其自己的域。为了改进Web应用程序,开发人员要求浏览器厂商允许跨域请求。

解决方案

1. 如何使用CORS策略来进行跨域操作

跨域资源共享(CORS)机制允许 Web 应用服务器进行跨域访问控制,从而使跨域数据传输得以安全进行。浏览器支持在发送AJAX请求中使用CORS来降低HTTP请求所带来的风险。

1.1 简单模式

response.setHeader('Access-Control-Allow-Origin','http://xxxxx.com:80')

1.2 复杂模式

在AJAX请求中,如果需要使用PUT/DELETE等高级方法时,会返回报错字符串'Access-Control-Allow-Method',也需要在后端服务器中设置来开放权限,加入以下语句:

response.setHeader('Access-Control-Allow-Method','GET,POST,OPTIONS')

即可得到'Access-Control-Allow-Method'内由后端指定开放的'GET,POST,OPTIONS'等权限。

2. 如何使用JSONP策略来进行跨域操作

2.1 核心逻辑

在浏览器中,只有XMLHttpRequestFetch会被同源原则限制,而script、css等直接请求的source和link并不会。利用这个特点,我们如果仅需要跨域来GET一个资源的话,可以直接使用<script>脚本来获得数据。

2.2 JSONP是什么

JSONP = JSON + Padding 是跨域获得的数据文件内容的一种简写方式。一般以JSONP为传输形式的返回文件格式写法如下,中间为JSON数据格式,前后有函数的包裹:

{{callback}}(
    {"name":"hikari", 
     "age":18
    });

2.3 实现方式

  function jsonp(url, fn) {
  var functionName = 'randomName' + parseInt(Math.random()*100000);
  window[functionName] = fn;

  var script = document.createElement('script');
  script.src = url + '?callback=' + functionName;
  document.head.appendChild(script)
  }
  {{callback}}({"name":"hikari", "qb":500});
  if(path === '/xxx.js'){
  var string = fs.readFileSync('./xxx.js','utf8')
  var callback = query.callback;
  response.setHeader('Content-Type', 'text/javascript;charset=utf-8')
  response.end(string.replace('{{callback}}',callback))
  }
jsonp('http://qq.com:81/xxx.js', function (data) {
  console.log('第一次的数据');
  console.log(data)
});
jsonp('http://qq.com:81/xxx.js', function (data) {
  console.log('第二次的数据');
  console.log(data)
});
randomName91058({"name":"hikari", "qb":500});

得到的控制台信息为

第一次的数据
{name: "hikari", qb: 500}
第二次的数据
{name: "hikari", qb: 500}

2.4 其他方法

jQuery也为JSONP设置了对应方法,可以直接调用。

$.ajax({
  url: 'http://qq.com:81/xxx.js',
  type: 'GET',
  dataType: 'jsonp',
  success: function(data){
    console.log('jquery得到的数据');
    console.log(data)
  }
});

得到的响应数据为:

jQuery21402045766844241943_1502793793916({"name":"hikari", "qb":500});

控制台结果为

jquery得到的数据
{name: "hikari", qb: 500}

总结

CORS策略 和 JSONP策略有何异同?

上一篇 下一篇

猜你喜欢

热点阅读