浏览器的跨域问题及其解决方法

来源:互联网 发布:js设置input文本颜色 编辑:程序博客网 时间:2024/05/17 21:59

跨域

由于浏览器的同源策略(请求的url地址,必须与浏览器上的url地址处于同一域上),不在同一域下的地址不能互相访问。同源是指,域名、协议、端口号都一致。

http://google.com 和 https://google.com 不同,因为协议不同;
http://sina.com:8080 和 http://sina.com:1000 不同,因为端口不同;
http://sina.com:8080 和 https://google.com 不同,协议、域名、端口号都不同。

同源策略分为以下两种:
DOM同源策略:禁止对不同源页面DOM进行操作。这里主要场景是iframe跨域的情况,不同域名的iframe是限制互相访问的。
XMLHttpRequest同源策略:禁止使用XHR对象向不同源的服务器地址发起HTTP请求。

跨域限制是为了安全性考虑。有了跨域的限制,我们访问页面就更加安全。如果没有同源策略,大家都可以随便通过ajax直接获取其他网站的信息,这样互联网就打乱了。

跨域的解决方法

<img>的src属性(获取图片),<link>的href属性(获取css),<script>的src属性(获取JavaScript)这三个都不符合同源策略,它们都可以跨域获取数据。

JSONP

JSONP,即JSON with padding,是为了解决跨域请求资源而产生的解决方案,是一种依靠开发人员创造出的一种非官方跨域数据交互协议。

注意:JSONP只支持get请求,不支持post请求。

凡是拥有scr这个属性的标签都可以跨域,例如<script><img><iframe>

<script>是没有同源限制的,就是利用src属性能够跨域访问的特性,所以可以通过<script>访问目标地址,通过传入的回调函数callback对返回的数据进行处理并返回。

导入JSONP库,封装JSONP

import originJSONP from 'jsonp';/** * @export * @param {String} url  跨域访问的地址 * @param {Object|Function} data   传递的参数对象options / callback * @param {Function} option  回调函数,就可以拿到数据,用ES6开发,更常用的使用Promise方法而不是回调函数 */export default function jsonp(url, data, option) {  url += (url.indexOf('?') < 0 ? '?' : '&') + param(data);  return new Promise((resolve, reject) => {    originJSONP(url, option, (err, data) => {      if (!err) {        resolve(data)      } else {        reject(err)      }    });  });}function param(data) {  let url = '';  for (var k in data) {    let value = data[k] !== undefined ? data[k] : '';    url += `&${k}=${encodeURIComponent(value)}`;  }  return url ? url.substring(1) : '';}

原生JS封装

function loadScript(xyUrl, callback){      var head = document.getElementsByTagName('head')[0];      var script = document.createElement('script');      script.type = 'text/javascript';      script.src = xyUrl;      script.onload = script.onreadystatechange = function(){          if((!this.readyState || this.readyState === "loaded" || this.readyState === "complete")){              callback && callback();              // Handle memory leak in IE              script.onload = script.onreadystatechange = null;//人工回收内存              if ( head && script.parentNode ) {                  head.removeChild( script );              }          }      };      head.insertBefore( script, head.firstChild );  }  //  var url = "http://todolist6.sinaapp.com/pages/QuickWayGetInfo.php?callback=showInfo";  loadScript(url, showInfo);  var showInfo = function(data){      console.log(data.name);  }  

跨域资源共享CORS(Cross-origin resource sharing)

阮一峰老师的跨域资源共享CORS详解讲解得非常好,值得一看。

简单的说一下过程就是:
对于客户端,我们还是正常使用xhr对象发送ajax请求。
需要注意的是,我们需要设置我们的xhr属性withCredentials为true,这个属性是为了设置是否可以携带cookie,没有设置的话,cookie是带不过去的哦,设置: xhr.withCredentials = true;

对于服务器端,需要在 response header中设置如下两个字段:
Access-Control-Allow-Origin: http://www.yourhost.com
Access-Control-Allow-Credentials:true
这样,我们就可以跨域请求接口了。

代理

例如www.123.com/index.html需要调用www.456.com/server.php,可以写一个接口www.123.com/server.php,由这个接口在后端去调用www.456.com/server.php并拿到返回值,然后再返回给index.html,这就是一个代理的模式。相当于绕过了浏览器端,自然就不存在跨域问题。

阅读全文
0 0
原创粉丝点击