同源策略
为了防止跨域请求伪造攻击,浏览器用同源策略的机制来保证安全。同源策略必须是:协议相同,域名相同,端口相同
JSONP
由于script脚本不受跨域限制,我们可以运用这个特性来请求数据,
我们可以发送一个带callback的请求到服务端,如www.abc.com/api?callback=func
, 而服务器根据你的callback
来返回json数据。这个例子会返回类似
func({
data: 'test'
})
由于你的func函数已经在本地定义好了, 上述返回的script脚本会直接运行你本地的代码,
function func(data) {
console.log(data)
}
通过这个原理我们可以动态添加script来调用, 一些库包括jQuery已经包装好了,我们可以直接使用
Hash
// 利用hash,场景是当前页面 A 通过iframe或frame嵌入了跨域的页面 B
// 在A中伪代码如下:
var B = document.getElementsByTagName('iframe');
B.src = B.src + '#' + 'data';
// 在B中的伪代码如下
window.onhashchange = function () {
var data = window.location.hash;
};
CORS 跨域访问
浏览器会检查服务器的响应头域,进而判断是否允许当前站点访问。 一些常见的响应头域有
Access-Control-Allow-Origin
Access-Control-Allow-Credentials
Access-Control-Allow-Methods
Access-Control-Allow-Headers
Access-Control-Expose-Headers
Access-Control-Max-Age
通过代理服务器请求
可以通过自己的服务器请求数据, 或者用代理服务器
Websocket
var ws = new WebSocket('wss://echo.websocket.org');
ws.onopen = function (evt) {
console.log('Connection open ...');
ws.send('Hello WebSockets!');
};
ws.onmessage = function (evt) {
console.log('Received Message: ', evt.data);
ws.close();
};
ws.onclose = function (evt) {
console.log('Connection closed.');
};
postMessage
//a.com/index.html
<iframe src="b.com/index.html" id="ifr">
</iframe>
<script>
window.onload = function(){
var iframe = document.getElementById('ifr');
var targetOrigin = 'http://b.com'; // 若写成'http://b.com/c/proxy.html'效果一样
// 若写成'http://c.com'就不会执行postMessage了
iframe.contentWindow.postMessage('data to send',targetOrigin);
}
</script>
// b.com/index.html
<script type="text/javascript">
window.addEventListener('message',function(event){
// 通过origin属性判断消息来源地址
if(event.origin == 'http://a.com'){
console.log(event.data);
console.log(event.source);
}
},false);
</script>
document.domain
通过修改document.domain
允许跨域的标签
img, link, script