• 跨浏览器 跨域资源共享 解决方案


    前言

      通过XHR实现ajax通信的一个主要限制是 跨域安全策略。XHR对象只能访问与包含他的页面位于同一个域的资源。当发起一个资源请求的时候,请求头会带有一个 Origin头部,响应头会带有一个Access-Origin-Allow-Origin,如下:

    Origin:http://www.test.com
    Access--Control-Allow-Origin: http://www.test.com
    // Access--Control-Allow-Origin: * // 代表公共资源

    如果这个头部和Origin头部不相符合的时候,浏览器会驳回请求。于是就出现了跨域请求技术,下面是几种方式的总结.

    实现一:跨浏览器的CORS

     1 function createCORSRequest(method,url) {
     2   var xhr = new XMLHttpRequest();
     3   if ("withCredentials" in xhr){
     4     xhr.open(method,url,true);
     5   }else if(typeof XDomainRequest!== "undifined"){
     6     xhr=new XDomainRequest();
     7     xhr.open(method,url);
     8   }else{
     9     xhr=null;
    10   }
    11   return xhr;
    12 }
    13 
    14 var request=createCORSRequest('get','http://www.test.com');
    15 if(request){
    16   request.onload=function(){
    17     // onreadystatechange检测成功
    18     // 处理 requset.responseText
    19   }
    20   request.onerror=function(){
    21     // 处理请求失败
    22   }
    23   requset.send(null);
    24 }

    上面是跨浏览器的实现方式,下面分析一下:

    IE对CORS的实现

      IE8中引入了XDR(XDomainRequest)类型,此类型和XMLHttpResquest相似,但是可以实现安全的跨域通信。

    不同之处:

    ①  不能通过setRequestHeader()设置自定义头部,只能设置请求头部信息的Content-Type字段,   xhr.contentType  

    ②  不能访问响应头信息,即调用getAllResponseHeaders()总是返回空字符串

    ③  不能发送和接受cookie

    XDR对象的方法

    ①  open() 只接受两个参数,所有XDR请求都是异步的

    ②  send() 同XHR对象一样

    其他事件

     1 var xdr=new XDomainRequest();
     2 xdr.onload=function(){
     3   //  xdr.responseText 响应的原始文本
     4   // 无法确定 响应的状态代码,即无 xhr.readyState和xhr.status
     5 }
     6 xdr.onerror=function(){
     7   alert("An error occurred.");
     8 }
     9 xdr.open('get',"url");
    10 xdr.send(null);

    其他浏览器对CORS的实现

      FireFox3.5+,Safari4+,Chrome等等都实现了原生CORS的支持。但是默认情况下,跨域请求不提供凭据,可以设置withCredentials表示带凭据的请求

    于是,设置跨浏览器的CORS的时候,可以先检测是否带  withCredentials 属性,若无,再检测是否存在XDomainRequest对象。

    实现二: 图像Ping

      可行性:网页可以从任何网页中加载图像,不用担心跨域问题。

      具体实现:利用 img 标签,动态创建图像。

    1 var img=new Image();
    2 img.onload=img.onerror=function(){
    3   alert("done");
    4 }
    5 img.src="http://www.example.com/test?name=Kasmine";

       这里创建了一个Image实例,通过 img.src 向服务器发起GET请求(参数为name),服务器收到请求后,通过对请求url的解析,判断请求内容。

      应用:图像Ping主要用于用户点击页面或者浏览量的统计。

      缺点:只有get请求,不能访问服务器的响应文本

    实现三: JSONP

      jsonp :“JSON with padding”顾名思义就是 包含在函数回调的json数据。具体实例如下:

    1 function handleResponse(response) {
    2   // 处理 response
    3 }
    4 var script=document.createElement("script");
    5 script.src='http://www.example.com?callback=handleResponse';
    6 document.body.insertBefore(script,document.body.firstChild);

    <script>标签和<img>标签一样,不受访问域的限制。首先我们创建一个 script 元素,插入到页面后立刻执行。客户端定义了一个名为handleResponse的回调函数,向 http://www.example.com 发起GET请求,服务器端进行响应:

    callback({"name":"Nicholes"});

    客户端在响应到来时,会调用 回调函数 handleResponse

    实现四:修改document.domain跨子域

      两个域名必须属于同一个基础域名

    实现五:通过使用HTML5的window.postMessage方法来传送数据

    始终使用origin和source属性验证发件人的身份

    1 窗口A:
    2 window.postMessage(msg,urlOfB);
    3 窗口B:
    4 window.onmessage(event){ 
    5      var data=event.data;
    6      var origin=event.origin;
    7 }

    小结 

      同源策略是XHR的一个约束,他要求“相同的域,相同的端口,相同的协议”才能进行通信。于是就出现了跨域访问的技术。

    实现 跨域还有其他的方法,在这里就不多说了,日后学习到了,再继续补上~

  • 相关阅读:
    为DataGrid 写一个 DropDownListColumn
    网页向女友告白和纪念日专用特效
    CentOS6.5 64位站点压力測试工具webbench
    RxJava系列之二 变换类操作符具体解释1
    C语言实现单链表节点的删除(带头结点)
    excel 补全全部空格
    Linux经常使用命令-文件搜索命令-文件搜索命令find
    错误代码: 1045 Access denied for user &#39;skyusers&#39;@&#39;%&#39; (using password: YES)
    Yocto tips (17): Yocto License问题:restricted license not whitelisted in LICENSE_FLAGS_WHITELIST
    二叉树的基本使用
  • 原文地址:https://www.cnblogs.com/kasmine/p/6440571.html
Copyright © 2020-2023  润新知