造成跨域的原因: 由于游览器的同源策略

同源策略: 指两个url其协议、host、端口号完全一致

例如: http://www.dengwz.com:80

协议是指:http

host是指 dengwz.com

端口号指:80

这个标准为两个URL 是否同源提供了理论依据

常用解决跨域的方法

  1. JSONP 跨域
  2. CORS 同源策略设置
  3. postMessage通信

JSONP 跨域

原理: 利用 游览器 对 <script> 标签 通过 src 加载远程 文件的不限制的特性

$.ajax({           
    url:"http://www.dengwz.com/services.php",           
    dataType:'jsonp',                     
    jsonp:'callback',           
    success:function(result) {              
          // some code         
    }      
 });  

以上是通过 jquery 里面的 ajax 的方式实现JSONP跨域

注意: AJAX通过XmlHttpRequest获取非本页内容, jsonp 是通过动态创建 <script>标签来调用服务器提供的js脚本 。他们只是在jquery框架下封装成在一起了,本质还有区别了。

JSONP跨域原理过程图

这里又涉及了一个知识点:标签中含有 async 标签,这个标签的作用

async的设置,会使得script脚本异步的加载并在允许的情况下执行
async的执行,并不会按script在页面中的顺序来执行,而是谁先加载完谁执行。

然后在看返回的JSONP内容是:

jQuery111105987283344131216_1567688234450({“a”:1,”b”:2})

这里 jQuery111105987283344131216_1567688234450 这就是通过URL传入的callback,里面的json 格式的数据就是我们需要的内容,

success:function(result) {              
  // some code         
}   

这里的 result 就等于那个 JSON 格式的数据,是不是明白了,其实是就是服务器接口返回了一个Js函数,而我们传递的数据,其实就是那个函数的里面的参数。 

JSONP的不足之处:

JSONP的优缺点:

    ​优点:

       不存在兼容性问题​

    缺点:

  1、只能使用get方法,不能使用post方法:

  2、没有关于 JSONP 调用的错误处理

CORS 同源策略设置

原理: CORS是一套解决前后端跨域通信的解决方案,简单说是一种前后端用于允许跨域通信的一种约定机制

服务器端设置

//允许www.dengwz.com的请求跨域
header("Access-Control-Allow-Origin:www.dengwz.com");

//设置通配符,允许所有请求跨域
header("Access-Control-Allow-Origin:*");

如果服务器入口文件没有设置 允许跨域,那么游览器会报错

若前端跨域请求而服务器不支持,游览器报警告图

这并不是一个错误,请求还是会发送的,就是被拦截了。任何返回都没有

若设置了,运行跨域,则跟jsonp 返回结果一致。

CORS策略的优缺点:

  优点:

1、CORS支持所有类型的HTTP请求。

2、 使用CORS,开发者可以使用普通的XMLHttpRequest发起请求和获得数据,比起JSONP有更好的错误处理。

  缺点:

 兼容性方面相对差一点,ie10或以上才支持

注意: 若你这个跨域请求需要携带cookies,前端代码需要修改一下

xhrFields:{         
   withCredentials:true    
}, 

后端代码:

//允许携带cookie
header('Access-Control-Allow-Credentials:true');

postMessage通信

这就比较高级,属于HTML5上面的新特性,在谷歌游览器插件里面也应用的比较广泛,属于页面级别的通信。属于消息类API。

window.postMessage() 方法可以安全地实现跨源通信。通常,对于两个不同页面的脚本,只有当执行它们的页面位于具有相同的协议通常为https),端口号443为https的默认值),以及主机  (两个页面的模数 Document.domain设置为相同的值) 时,这两个脚本才能相互通信。

window.postMessage 权威指南
// 发送消息
window.postMessage(message, targetOrigin, [transfer]) 

//监听
window.addEventListener('message',function(e){
    if(e.origin == 'http://www.dengwz.com'){
        console.log(JSON.parse(e.data));
    }
})

你这样理解,我在页面上面安装了一个监听器,然后其他页面的通过postMessage 发送广播,我这边监听器监听到了,然后判断是不是,监听域发来的数据。

postMessage的优缺点:

  优点: 方便,安全,有效的解决了跨域问题

  缺点: 兼容性方面相对差一点,IE8 以下不支持,IE9部分支持PostMessage特性,主要体现在,数据传输只能发送string类似的字符串,而标准的postMessage消息数据可以是任何类型

Leave a Reply

Your email address will not be published. Required fields are marked *