跨域解决方案介绍2,转自github.

跨域问题

浏览器的安全基石是“同源政策”,所谓同源是指协议相同,域名相同,端口相同,只要其中有一个不同,则称为不同源。不同源的网站之间不能够相互请求数据,以确保用户数据的安全性。 但有的时候,一个网站不得不请求别的域上面的数据,这个过程就称为跨域。

跨域的实现方法有以下几种:

(1)JSONP

JSONP(JSON with padding)的原理是script标签不受同源安全策略限制,它可以向别的域发送get请求。

function handleResponse(data) {
	console.log('The response data is:' + data);
}
//动态添加script标签
var script = document.createElement('script');
script.src = 'http://www.baidu.com/json?callback=handleResponse';
script.setAttribute('type', 'text/javascript');
document.body.appendChild(script);

后台收到get请求后,根据callback参数生成相应的JSONP数据 handleResponse({'data': serverdata}),这段数据返回前端就会被当作js代码执行,触发回调函数。

jQuery和JSONP

$(document).ready(function(){
	$.ajax({
		type: 'get',
		async: false,
		// 查询CA1998次航班的信息
		url: 'http://flightQuery.com/jsonp/flightResult.aspx?code=CA1998',
		dataType: 'jsonp',
		//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(一般默认为:callback)
		jsonp: 'callback',
		//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名,也可以写"?",jQuery会自动为你处理数据
		jsonpCallback: 'flightHandler',
		success: (json) => {
			alert('您查询到航班信息:票价: ' + json.price + ' 元,余票: ' + json.tickets + ' 张。');
		},
		error: () => {
			alert('fail');
		}
	});
});

(2)CORS

CORS是一个W3C标准,全称为跨域资源共享(cross-origin resource sharing),它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。

整个CORS通信过程都由浏览器自动完成,用户不需要参与,对于前端开发者来说,同源ajax和CORS的代码完全相同,因此,实现CORS的关键在于服务器是否提供CORS接口。

简单请求例子:

GET /cors HTTP/1.1
Origin: http://api.bob.com
Host: api.alice.com
Accept-Language: en-US
Connection: keep-alive
User-Agent: Mozilla/5.0...

若服务器允许来自http://api.bob.com的跨域请求,则会进行如下响应:

Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true  //是否允许发送cookie
Access-Control-Expose-Headers: FooBar  // 额外的header字段
Content-Type: text/html; charset=utf-8

若不允许,则不会设置Access-Control-Allow-Origin字段,如果服务器将此字段设为*,则表示服务器接受所有域的跨域请求。

Access-Control-Allow-Credentials: true 则表明服务器接受cookie,同时开发者应在AJAX打开withCredentials属性,以允许浏览器发送cookie:

var xhr = new XMLHttpRequest();
xhr.withCredentials = true;

跨域资源共享 CORS 详解

(3)iframe + HTML5 postMessage

即不同window间通过HTML5的API postMessage进行跨域通信,其格式为:

otherWindow.postMessage(data, targetOrigin);
// otherWindow指要接收消息的窗口,targetOrigin限制接收窗口所在的域,若不想限制,设为*即可

示例:

<!--a.com/index.html-->
<iframe id="ifr" src="b.com/index.html"></iframe>
<script type="text/javascript">
window.onload = function() {
    var ifr = document.getElementById('ifr');
    var targetOrigin = 'http://b.com';  // 若写成'http://b.com/c/proxy.html'效果一样
                                        // 若写成'http://c.com'就不会执行postMessage了
    ifr.contentWindow.postMessage('Message from a.com!', targetOrigin);
};
</script>
<!--b.com/index.html-->
<script type="text/javascript">
    window.addEventListener('message', function(event){
        // 通过origin属性判断消息来源地址
        if (event.origin == 'http://a.com') {
            alert(event.data);    // 弹出"Message from a.com!"
            alert(event.source);  // 对a.com、index.html中window对象的引用
                                  // 但由于同源策略,这里event.source不可以访问window对象
        }
    }, false);
</script>

(4)iframe + window.name

原理: windoe.name 的值在不同的页面(甚至不同域名)加载后依旧存在,并且可以支持非常长的 name 值(2MB)

a.com/1.html

<script type="text/javascript">
function getData() {
	var ifr = document.getElementById('proxy');
	ifr.src = 'a.com/2.html'; //跳转到同源网站
	ifr.onLoad = function() {
		var data = ifr.contentWindow.name;
		alert(data);
	}
}
</script>
<iframe src='http://other-origin/data.html' style='display:none' onLoad='getData()'></iframe>

other-origin/data.html

var data = {
	name: 'xiaoming',
	age: 12
};
window.name = JSON.stringify(data);

(5)WebSocket

WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。

请求头信息:(多了个 origin)
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com

响应头:(如果origin在白名单内)
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏菩提树下的杨过

Flash/Flex学习笔记(4):如何打开网页及Get/Post数据

flash终究只是客户端技术,所以很多时候还是需要与服务端技术(比如asp,asp.net,jsp,php之类)进行数据交互的,下面的代码演示了如何在flash...

1837
来自专栏carven

cors跨域探讨

前端跨域方案很多,jsonp、iframe等等,但是个人觉得,最正宗,最无损的跨域方式还是CORS。 CORS(Cross-origin resource sh...

1240
来自专栏java一日一条

HTTPRequest类

HTTPRequest 封装通过 URLFetchService 进行的单个 HTTP 请求。

956
来自专栏java一日一条

HTTPRequest类

HTTPRequest 封装通过 URLFetchService 进行的单个 HTTP 请求。

301
来自专栏王磊的博客

WebApi开启CORS支持跨域POST

概念:CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHtt...

3738
来自专栏大内老A

通过扩展让ASP.NET Web API支持W3C的CORS规范

让ASP.NET Web API支持JSONP和W3C的CORS规范是解决“跨域资源共享”的两种途径,在《通过扩展让ASP.NET Web API支持JSONP...

2258
来自专栏马涛涛的专栏

同源策略与CORS跨域

PS:这篇文章是紧接着JSONP原理和Ajax学习与理解写的,有些内容是承接了上两篇文章. 这篇文章只算是我的个人学习笔记,内容没有经过精心排版,也没有认真校对...

572
来自专栏Golang语言社区

Golang web服务器处理前端HTTP请求跨域的方法

package main import ( "flag" "fmt" "net" "net/http" ) type httpServer struct { }...

3555
来自专栏微信小程序开发

ajax跨域有没有踩过坑,IE低版本浏览器如何支持?

同源策略 为了保证用户信息的安全,防止恶意的网站窃取数据,所有的浏览器都实行这个策略。 同源策略是指,用户在A网页上的所产生的信息,B网页上不能访问,反过来A...

39710
来自专栏me的随笔

同源策略与CORS

不同源下,浏览器不允许js操作Cookie、LocalStorage、DOM等数据或页面元素,也不允许发送ajax请求,同源下则不受影响。

1064

扫码关注云+社区