zoukankan      html  css  js  c++  java
  • 实现跨域的几种方法

    一、xhr

    浏览器中支持情况:

    • Chrome 3+
    • Firefox 3.5+
    • Opera 12+
    • Safari 4+
    • Internet Explorer 8+

    Chrome,Firefox,Opera和Safari都使用XMLHttpRequest2对象。 Internet Explorer使用了类似的XDomainRequest对象,其工作原理和XMLHttpRequest大致相同,但增加了额外的安全预防措施。

    1.创建请求对象

      在网上搜了一个简单的辅助方法来理清浏览器的差异:

    function createCORSRequest(method, url) {  
      var xhr = new XMLHttpRequest();
      if ("withCredentials" in xhr) {
    
        // 检查XMLHttpRequest对象是否有 "withCredentials" 属性
        // 只有XMLHTTPRequest2对象有"withCredentials"属性
        xhr.open(method, url, true);
    
      } else if (typeof XDomainRequest != "undefined") {
    
        // 否则, 检查是否为XDomainRequest.
        // XDomainRequest只在IE中被支持
        xhr = new XDomainRequest();
        xhr.open(method, url);
    
      } else {
    
        // 否则, 浏览器不支持CORS
        xhr = null;
    
      }
      return xhr;
    }
    
    var xhr = createCORSRequest('GET', url);  
    if (!xhr) {  
      throw new Error('CORS not supported');
    }

    2.事件处理

    最原始的XMLHttpRequest对象只有一个用来处理所有响应的事件处理程序onreadystatechange。虽然onreadystatechange依然可用,但是XMLHttpRequest2引入了很多新的事件处理程序。下面就是完整的清单:

    • onloadstart*:请求开始
    • onprogress:加载和发送数据中
    • onabort*:请求中断,例如调用abort()方法
    • onerror:请求失败
    • onload:请求成功
    • ontimeout:请求超过了用户设定的超时时间
    • onloadend*:请求结束(无论失败还是成功)

    (加*的不被IE的XDomainRequest支持)

    在大多数情况下,你至少要处理的onload和onerror的事件:

    xhr.onload = function() {  
     var responseText = xhr.responseText;
     console.log(responseText);
     // 处理响应
    };
    
    xhr.onerror = function() {  
      console.log('There was an error!');
    };

    当发生错误时,浏览器在报告哪里出了问题上做的并不好。例如,Firefox对于所有的错误报告0状态和空状态文本。浏览器也会报告错误信息到控制台日志,但此消息无法通过JavaScript访问。当处理onerror时,你就会知道发生了错误。

    3.发送请求

    xhr.send();  

    如果请求包含请求体,那么请求体可以作为参数传入send()

    二、图像Ping
    复制代码
    var img=new Image();
    
    img.onload=img.onerror=function(){
    
         alert(1);
    
    };
    
    img.src="http://www,fuwuqi.com?name=tong";
    复制代码

    简单单向跨域通信的方式,只能发送get请求,无法访问服务器的响应文本

    三、JSONP

    var s=document.createElement("script");
    s.src="http://fuwuqi.com?name=tong&callback=cb";
    document.body.insertBefore(s,document.body.firstElementChild||document.body.children[0]);
    在其他域中加载代码执行,不安全;
    检测请求是否失败不容易
     
    四、web socket 后面有专门介绍
    五、postMessage

    postMessage(data,origin)方法接受两个参数

    1.data:要传递的数据,html5规范中提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点儿,部分浏览器只能处理字符串参数,所以我们在传递参数的时候需要使用JSON.stringify()方法对对象参数序列化,在低版本IE中引用json2.js可以实现类似效果。

    2.origin:字符串参数,指明目标窗口的源,协议+主机+端口号[+URL],URL会被忽略,所以可以不写,这个参数是为了安全考虑,postMessage()方法只会将message传递给指定窗口,当然如果愿意也可以建参数设置为"*",这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为"/"。

    http://test.com/index.html

     
    <div >
            <div id="color">Frame Color</div>
        </div>
        <div>
            <iframe id="child" src="http://lsLib.com/lsLib.html"></iframe>
        </div>
    </div>

    我们可以在http://test.com/index.html通过postMessage()方法向跨域的iframe页面http://lsLib.com/lsLib.html传递消息

    window.onload=function(){
                window.frames[0].postMessage('getcolor','http://lslib.com');
            }

    接收消息

    test.com上面的页面向lslib.com发送了消息,那么在lslib.com页面上如何接收消息呢,监听window的message事件就可以

    http://lslib.com/lslib.html

    window.addEventListener('message',function(e){
                    if(e.source!=window.parent) return;
                    var color=container.style.backgroundColor;
                    window.parent.postMessage(color,'*');
                },false);
    

    这样我们就可以接收任何窗口传递来的消息了,为了安全起见,我们利用这时候的MessageEvent对象判断了一下消息源,MessageEvent是一个这样的东西

    有几个重要属性

    1. data:顾名思义,是传递来的message
    2. source:发送消息的窗口对象
    3. origin:发送消息窗口的源(协议+主机+端口号)

    这样就可以接收跨域的消息了,我们还可以发送消息回去,方法类似

    简单的demo

    在例子中页面加载的时候主页面向iframe发送’getColor‘ 请求(参数没实际用处)

    window.onload=function(){
                window.frames[0].postMessage('getcolor','http://lslib.com');
            }

    iframe接收消息,并把当前颜色发送给主页面呢

    window.addEventListener('message',function(e){
                    if(e.source!=window.parent) return;
                    var color=container.style.backgroundColor;
                    window.parent.postMessage(color,'*');
                },false);
    

    主页面接收消息,更改自己div颜色

    window.addEventListener('message',function(e){
                var color=e.data;
                document.getElementById('color').style.backgroundColor=color;
            },false);
    

    当点击iframe事触发其变色方法,把最新颜色发送给主页面

     
    function changeColor () {            
                    var color=container.style.backgroundColor;
                    if(color=='rgb(204, 102, 0)'){
                        color='rgb(204, 204, 0)';
                    }else{
                        color='rgb(204,102,0)';
                    }
                    container.style.backgroundColor=color;
                    window.parent.postMessage(color,'*');
                }
     

    主页面还是利用刚才监听message事件的程序处理自身变色

    window.addEventListener('message',function(e){
                var color=e.data;
                document.getElementById('color').style.backgroundColor=color;
            },false);
    
  • 相关阅读:
    android 75 新闻列表页面
    android 74 下载文本
    android 73 下载图片
    android 72 确定取消对话框,单选对话框,多选对话框
    android 71 ArrayAdapter和SimpleAdapter
    android 70 使用ListView把数据显示至屏幕
    maven如何将本地jar安装到本地仓库
    Centos6.7搭建ISCSI存储服务器
    解决maven打包编译出现File encoding has not been set问题
    MySQL 解决 emoji表情 的方法,使用utf8mb4 字符集(4字节 UTF-8 Unicode 编码)
  • 原文地址:https://www.cnblogs.com/shytong/p/4959150.html
Copyright © 2011-2022 走看看