前端跨域解决方法总结

同源策略:
所谓同源策略,指的是浏览器对不同源的脚本或者文本的访问方式进行的限制。
同源:协议相同,域名相同,端口相同。
同源策略主要带来三个方面的行为限制:
1、cookie,localstorage和IndexDB无法读取
2、DOM无法获取
3、Ajax请求不能发送规避方法:

跨域方法总结
1、JSONP
优点:简单易用,浏览器支持好。
缺点:
1. JSONP是从其他域中加载代码并执行,所以存在很多安全隐患,如果其他服务器在响应中夹带恶意代码的话,没有办法防范。
2. JSONP难以确定请求失败的情况。HTML5中给<script>元素增加了一个onerror事件,但是还是有浏览器不支持。
3. 只能发送GET请求

2、图像Ping:
一个网页可以从任何网页中加载图像。图像ping这是指通过请求图片的方式来跨域发送请求。动态创建图像经常用于图像 Ping。图像 Ping 是与服务器进行简单、单向的跨域通信的一种方式。 请求的数据是通过查询字符串形式发送的,而响应可以是任意内容,但通常是像素图或 204响应。通过 图像 Ping,浏览器得不到任何具体的数据,但通过侦听 load 和 error 事件,它能知道响应是什么时 候接收到的。中发送了一个 name 参数。 图像 Ping常用于跟踪用户点击页面或动态广告曝光次数。
优点:简单,兼容性好,不需要服务器做针对性处理。
缺点:
1. 只能单向通信,即客户端发送信号给服务端,无法接收到服务端的回复
2. 只能发送GET请求
3. 容易被浏览器缓存请求,导致请求发送不出去。

var img = new Image();
img.onload = img.onerror = function () {
    alert("Done!");
};
img.src = "http://www.example.com/test?name=Nicholas";

3、CORS
CORS是Cross-Origin Resource Sharing的缩写,即跨域资源共享。CORS的基本思想就是使用自定义的HTTP头部让浏览器与服务器进行沟通,从而决定请求或响应是应该成功,还是应该失败。
例子:比如一个简单的使用 GET 或 POST 发送的请求,它没有自定义的头部,而主体内容是 text/plain。在 发送该请求时,需要给它附加一个额外的 Origin 头部,其中包含请求页面的源信息(协议、域名和端 口),以便服务器根据这个头部信息来决定是否给予响应。下面是 Origin 头部的一个示例:Origin: http://www.nczonline.net。如果服务器认为这个请求可以接受,就在 Access-Control-Allow-Origin 头部中回发相同的源信息(如果是公共资源,可以回发”*”)。例如:Access-Control-Allow-Origin: http://www.nczonline.net。如果没有这个头部,或者有这个头部但源信息不匹配,浏览器就会驳回请求。正常情况下,浏览器会处理请求。注意,请求和响应都不包含 cookie信息。
优点:功能强大
缺点:
1. 需要服务端来配合实现
2. IE必须IE10以上。。。

function createCORSRequest(method,url){
    var xhr=new XMLHttpRequest();
    if("withCredentials" in xhr){
        xhr.open(method,url,true);
    }else if(typeof XDomainRequest !="undefined"){
        xhr=new XDomainRequest();
        xhr.open(method,url);
    }else{
        xhr=null;
    }
    return xhr;
}

4、WebSocket
优点:
1. 双工通信,浏览器和服务器都可以发起请求
2. 通信效率高,一次链接可以复用,省去反复的握手环节
缺点:
1. 实现上较为复杂,包括客户端和服务端
2. 浏览器支持问题
Web Sockets的目标是在一个单独的 持久连接上提供全双工、双向通信。在 JavaScript中创建了 Web Socket之后,会有一个 HTTP请求发送到浏览器以发起连接。在取得服务器响应后,建立的连接会使用 HTTP 升级从 HTTP 协议交换为 Web Socket 协议。也就是说,使用标准的 HTTP 服务器无法实现 Web Sockets,只有支持这种协议的专门服 务器才能正常工作。 由于 Web Sockets使用了自定义的协议,所以 URL模式也略有不同。未加密的连接不再是 http://, 而是 ws://;加密的连接也不是 https://,而是 wss://。在使用 Web Socket URL时,必须带着这个 模式,因为将来还有可能支持其他模式。
使用自定义协议而非 HTTP协议的好处是,能够在客户端和服务器之间发送非常少量的数据,而不 必担心 HTTP那样字节级的开销。由于传递的数据包很小,因此 Web Sockets非常适合移动应用。

6、Comet
Comet指的是一种更高级的 Ajax技术(经常也有人称为“服务器 推送”)。Ajax 是一种从页面向服务器请求数据的技术,而 Comet 则是一种服务器向页面推送数据的技 术。Comet能够让信息近乎实时地被推送到页面上,非常适合处理体育比赛的分数和股票报价。
有两种实现 Comet的方式:长轮询和流。
长轮询是传统轮询(也称为短轮询)的一个翻版,即浏览器定时向服务器发送请求,看有没有更新的数据。长轮询把短轮询颠倒了一下。页面发起一个到服务器的请求,然后服务器一直保持连接打开,直到有数据可发送。发送完数据之后,浏览器关闭连接,随即又发起一个到服务器的新请求。这一过程在页 面打开期间一直持续不断。无论是短轮询还是长轮询,浏览器都要在接收数据之前,先发起对服务器的连接。两者大的区别 在于服务器如何发送数据。短轮询是服务器立即发送响应,无论数据是否有效,而长轮询是等待发送响 应。轮询的优势是所有浏览器都支持,因为使用 XHR对象和 setTimeout()就能实现。而你要做的就是决定什么时候发送请求。
第二种流行的 Comet实现是 HTTP流。流不同于上述两种轮询,因为它在页面的整个生命周期内只 使用一个 HTTP连接。具体来说,就是浏览器向服务器发送一个请求,而服务器保持连接打开,然后周期性地向浏览器发送数据。所有服务器端语言都支持打印到输出缓存然后刷新(将输出缓存中的内容一次性全部发送到客户 端)的功能。而这正是实现 HTTP流的关键所在。 在 Firefox、Safari、Opera和 Chrome中,通过侦听 readystatechange 事件及检测 readyState 的值是否为 3,就可以利用 XHR 对象实现 HTTP 流。在上述这些浏览器中,随着不断从服务器接收数 据,readyState 的值会周期性地变为 3。当 readyState 值变为 3时,responseText 属性中就会保 存接收到的所有数据。此时,就需要比较此前接收到的数据,决定从什么位置开始取得新的数据。使 用 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!");
});

7、服务器发送事件
SSE(Server-Sent Events,服务器发送事件)是围绕只读 Comet交互推出的 API或者模式。SSE API 用于创建到服务器的单向连接,服务器通过这个连接可以发送任意数量的数据。服务器响应的 MIME 类型必须是 text/event-stream,而且是浏览器中的 JavaScript API 能解析格式输出。SSE 支持短轮 询、长轮询和 HTTP流,而且能在断开连接时自动确定何时重新连接。有了这么简单实用的 API,再实 现 Comet就容易多了。

**注意:**SSE与Web Sockets 面对某个具体的用例,在考虑是使用 SSE还是使用 Web Sockets时,可以考虑如下几个因素。
首先, 你是否有自由度建立和维护 Web Sockets服务器?因为 Web Socket协议不同于 HTTP,所以现有服务器 不能用于 Web Socket通信。SSE倒是通过常规 HTTP通信,因此现有服务器就可以满足需求。
第二个要考虑的问题是到底需不需要双向通信。如果用例只需读取服务器数据(如比赛成绩),那 么 SSE 比较容易实现。如果用例必须双向通信(如聊天室),那么 Web Sockets 显然更好。别忘了,在 不能选择 Web Sockets的情况下,组合 XHR和 SSE也是能实现双向通信的。

猜你喜欢

转载自blog.csdn.net/mangxi8200/article/details/81476899