web前端跨域方案

时间:2023-03-08 16:54:51

ajax跨域请求   qzfl实现

  跨子域的xhr

  • 原生xhr不支持跨域,通过iframe+proxy.html达到跨子域
  • 假如A页面要请求B页面,A、B跨子域。A创建指向B的proxy页的iframe,将目的url、回调方法挂在iframe属性上,proxy通过frameElement获取目的url发送xhr请求后回调由A页面设置在iframe上的回调方法达到代理请求的目的。

  跨全域的get请求jsonp

  • jsonp可以跨全域,但只支持get方式。利用的是script标签没有域名限制的特性

  跨全域的post请求formSend

  • 通过构造带form表单的iframe,并将回调方法挂在iframe,提交form产生post请求,调用frameElement.callback回调。需要cgi返回符合协议格式
      <html>
    <head><meta http-equiv="Content-Type" content="text/html;charset=gb2312" /></head>
    <body><script type="text/javascript"> document.domain="qq.com"; frameElement.callback({JSON:"Data"}); </script></body>
    </html>

下载源码:qzfl_2.1.27.js

xhr2.0

  HTML5的XMLHttpRequest 2.0 在旧浏览器支持的XMLHttpRequest对象升级后,且向前兼容。

如何判断是否支持XHR 2.0?

网页端

  new XMLHttpRequest().withCredentials==="undefined" 有withCredentials属性则支持XMLHttpRequest 2.0。

  如果是使用jquery,ajax参数要设置下

    $.ajaxSetup({
// dataType: 'json',
xhrFields: {withCredentials: true}
});

服务器端

例如PHP:header('Access-Control-Allow-Origin: http://someotherdomain.com');

  withCredentials 默认为false,不会发送目标域名的cookie。手动设为true后,且服务器Access-Control-Allow-Credentials设置为true时,则可发送和接受到目标域名的cookie。

header('Access-Control-Allow-Origin: http://qgroup.qq.com');
header("Access-Control-Allow-Credentials: true");

XHR2.0的新特性?

  1.可发送跨域(子域)请求,在请求头中携带Origin属性,这个属性由浏览器生成无法修改。用来给服务器判断来源是否合法。

  2.XHR的新接口api在保持向前兼容的同时,更简洁实用。

    XMLHttpRequest(.upload)--onload、onerror、onabort、onprogress =fn  上传请求和返回响应阶段都可以定义回调方法,特别是onprogress是完全新增的功能

    xhr.upload.onprogress=function(e){

      e.loaded/e.total    

    }

  3.支持二进制数据,xhr.send(ArrayBuffer/Bolb)

 跨域通信

 postMessage+navigator方式

    iframe跨域通信在高级浏览器上可以通过html5 postMessage接口实现,在ie6、7下可以通过navigator共享来解决。

    参考链接:http://www.alloyteam.com/2013/11/the-second-version-universal-solution-iframe-cross-domain-communication/

  postMessage通信

  A主页面要跟B iframe嵌入页面通信

  A.js:

    document.getElementById("B").contentWindow.postMessage(data,domain);

  B.js:

    B.addEventListener("message",callbackB,true);

  B iframe页面要跟A主页面通信

  B.js:

    window.top.postMessage(data,domain);

  A.js:

    window.addEventListener("message",callbackA,true);

  window.name方式

    实现跨域主动拉取页面数据,页面数据应该是无状态的静态数据。

      事例:A页面存有一个UI组件的dom、js、css,B页面非同域情况下要获取A的ui组件信息我们通常会用<script>方式,但这一script里要包含html和css格式会很难看,通过A页面将UI数据存在window.name中,B页面创建       iframe先请求A页面获取window.name值后跳转到about:blank页,因为每个域名下都有个about:blank页面,这样B就能取得window.name,间接与A通信成功了。

    但这种业务场景比较特殊,适用不广泛。参考链接:http://www.cnblogs.com/rubylouvre/archive/2012/07/30/2614904.html