跨域的几种方式

跨域的主要方式是CORS

CORS(Cross-Origin Resource Sharing,跨资源共享)是W3C的一个工作草案,定义了在必须访问跨源资源时,浏览器与服务器应该如何沟通。CORS背后的基本思想,就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功还是应该失败。

下面是Origin头部的一个示例:
Origin:http://www.nczonline.net

如果服务器认为这个请求可以接受,就在Access-Control-Allow-Origin头部中回发相同的源信息(如果是公共资源,可以回发“*”)。例如:
Access-Control-Allow-Origin:http://www.nczonline.net

如果没有这个头部,或者有这个头部但源信息不匹配,浏览器就会驳回请求。

IE对CORS的实现是利用XDR(XDomainRequest)对象,其他浏览器是利用XHR(XMLHttpRequest)对象,所以跨浏览器的CORS可以这样写:
function createCORSRequest(method,url){
    var xhr=new XMLHttpRequest();
    if("withCredentials" in xhr){
        xhr.open(method,url,true);
    }else if(typeof XDomainRequest !="undefined"){
        vxhr=new XDomainRequest();
        xhr.open(method,url);
    }else{
        xhr=null;
    }
    return xhr;
}

var request=createCORSRequest("get","http://www.somewhere-else.com/page/");

if(request){
    request.onload=function(){
        //对request.responseText进行处理
    };
    request.send();
}

默认情况下,跨源请求不提供凭据(cookie、HTTP认证及客户端SSL证明等)。通过将withCredentials属性设置为true,可以指定某个请求应该发送凭据。如果服务器接收带凭据的请求,会用下面的HTTP头部来响应。

Access-Control-Allow-Credentials: true 

其他跨域技术

一、图像Ping

图像Ping是与服务器进行简单、单向的跨域通信的一种方式。

var img=new Image();
img.onload=img.onerror=function(){
    alert("Done!");
};

img.src="http://www.example.com/test?name=Nicholas";

缺点:
1.只能发送GET请求
2.无法访问服务器的响应文本

二、JSONP

JSONP是JSON with padding(填充式JSON或参数式JSON)的简写。JSONP看起来与JSON差不多,只不过是被包含在函数调用中的JSON,就像下面这样:

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

JSONP由两部分组成:回调函数和数据。回调函数的名字一般是在请求中指定的,而数据就是传入回调函数中的JSON数据,下面是一个典型的JSONP请求:

http://freegeoip.net/json/?callback=handleResponse

JSONP是通过动态

function handleResponse(response){
    alert("You're at IP address"+response.ip+",which is in"+response.city+","+response.region_name);
}

var script=document.createElement("script");
script.src="http://freegeoip.net/json/?callback=handleResponse";
document.body.insertBefore(script,document.body.firstChild);

优点:
能够直接访问响应文本,支持在浏览器和服务器之间双向通信

缺点:
1.JSONP是从其他域中加载代码执行,如果其他域不安全,就要放弃对JSONP的调用
2.要确定JSONP请求是否失败并不容易

三、Comet

Ajax是一种从页面向服务器请求数据的技术,而Comet则是一种服务器向页面推送数据的技术。
有两种实现Comet的方式:长轮询和流

1、长轮询:
页面发起一个到服务器的请求,然后服务器一直保持打开,直到有数据可发送。发送完数据后,浏览器关闭连接,随即又发起一个到服务器的新请求。这一过程在页面打开期间一直持续不断。

2、HTTP流:
不同于轮询,流在页面的整个生命周期内只使用一个HTTP连接。具体来说,就是浏览器向服务器发送一个请求,而服务器保持连接打开,然后周期性地向浏览器发送数据。
下面这段PHP脚本就是采用流实现的服务器中常见的形式:

<?php
    $i=0;
    while(true){
        //输出一些数据,然后立即刷新输出缓存
        echo "Number is $i";
        flush();
        //等几分钟
        sleep(10);
        $i++;
    }
?>

所有 服务器端语言都支持打印到输出缓存然后刷新(将输出缓存中的内容一次性全部发送到客户端)的功能。而这正是实现HTTP流的关键所在。

使用XHR对象实现HTTP流的典型代码如下所示:

function createStreamingClient(url,progress,finished){
    var xhr=new XMLHttpRequest(),
    received=0;

    xhr.open("get",url,true);
    xhr.onreadystatechange=function(){
        var result;

        if(xhr.readyState==3){
            //只取得最新数据并调整计数器
            result=xhr.responseText.substring(received);
            received+=result.length;

            //调用progress回调函数
            progress(result);
        }else if(xhr.readyState==4){
            finished(xhr.responseText);
        }

    };
    xhr.send(null);
    return xhr;
}

var client=createStreamingClient("streaming.php",function(data){
    alert("Received:" + data);
},function(data){
    alert("Done!");
});
四、服务器发送事件

SSE(Server-Sent Events,服务器发送事件)是围绕只读Comet交互推出的API或者模式。SSE API用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。SSE支持短轮询、长轮询和HTTP流,而且能在断开连接时自动确定何时重新连接。
用法:
1.创建一个新的EventSource对象,并传进一个入口点:

var source=new EventSource("myevents.php");

2.服务器发回的数据以字符串形式保存在event.data中:

source.onmessage=function(event){
    var data=event.data;
    //处理数据
}
五、Web Sockets

Web Sockets的目标是在一个单独的持久连接上提供全双工、双向通信。使用标准的HTTP服务器无法实现Web Sockets,只有支持这种协议的专门服务器才能正常工作。
由于Web Sockets使用了自定义的协议,所以URL模式也略有不同。未加密的连接不再是http://,而是ws://,加密的连接也不是https://,而是wss://。

用法:
1、实例一个WebSocket对象并传入要连接的URL:

var socket=new WebSocket("ws://www.example.com/server.php");

2、发送和接收数据:

socket.send("Hello world!");

因为Web Sockets只能通过连接发送纯文本数据,所以对于复杂的数据结构,在通过连接发送之前,必须进行序列化。下面的例子展示了先将数据序列化为一个JSON字符串,然后再发送到服务器:

var message={
    time:new Date(),
    text:"Hello world",
    clientId:"asdfp8734rew"
};

socket.send(JSON.stringify(message));

处理数据:

socket.onmessage=function(event){
    var data=event.data;
    //处理数据
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值