常见的跨域cors(跨源资源共享),JSONP,postMessage、websocket。先介绍两个专有名词:
CSRF(跨站点请求伪造),XSS(跨站点脚本)。
1.cors的基本思想:
使用自定义的HTTP头部和让浏览器和服务器进行沟通。如果服务器认为这个请求可以接受,就在Acces-control-Allow-Orign头部中发挥相同的源信息。
1)它的基本原理还是ajax,除了IE外其他浏览器基本都是利用XMLHttpRequest实现的,但是跨域的XHR还是有一些限制的:
不能使用setRequestHeader()设置自定义的头部。
不能发送和接受cookie
调用getAllResponseHeaders()总会返回空字符串
2)而IE是利用XDomainRequest来实现的:
不能接受和发送cookie
不能访问响应头部信息
只支持get和post请求
只能设置请求头部信息的content-type请求
3)所以为了兼容,可以有以下的简单写法:
var xhr = new XMLHttpRequest();
if ('widthCredentials' in xhr) {
xhr.open(method, url, true);
} else if (typeof XDomainRequest!='undefined') {
xhr = new XDomainRequest();
xhr.oepn(method, url);
} else {
xhr = null;
}
xhr.send();
2.JSONP
JSONP是利用script的实现去请求并加载不同源的资源。使用src请求一个跨域的URL。都不受限制的从其他域加载资源。
例如:var script =document.createElemet('script');
script.src = 'www.com?callback=handle';//url有回调函数和数据组成
documnet.body.insertBefor(script, document.body.firstChild);
优点:使用起来简单。兼容性好,在老浏览器中也可以使用。
缺点:不安全(有可能加载不安全的资源),不容易确定请求的成功或失败。
与cors相比:
cors能实现所有的http请求,而jsonp只能实现get请求。
cors可以更好的处理数据,而jsonp不可以。
jsonp主要支持老浏览器。
3.webSocket
webSocket目标提供一个全双工、双向通信的持久连接。在js中建立web socket后,会有一个http请求发起连接。在取得服务器的响应后,慧聪http协议交换为web socket协议。 未加密的连接不再是http://,而是ws://。https://对应的是wss://
例子:var socket = new WebSocket('ws://www.aaaa.com');
socket.send('message');
//由于socket只能发送纯文本数据,所以对一些复杂的数据要将其转换为字符串,如JSON对象,通过JSON.stringfy转换为字符串
//使用message接收事件,并接收数据在event.data中
socket.onmessage =function(event){
console.log(event.data)
}
4.Window.postMessage
postmessage是html5新增的。它与巽两个窗口Ifrmae间发送消息。它允许的实在页面即客户端间的通信,并不是浏览器和客户端间的通信
postMessage(data,origin)
data:需要传递的数据,html5规范提到该参数可以是JavaScript的任意基本类型或可复制的对象,然而并不是所有浏览器都做到了这点,部分浏览器只能处理字符串参数,所以我们在传递从参数的时候需要使用JSON.stringify()方法对对象参数序列化。
Origin:字符串参数,指明目标窗口的源,协议+主机+端口号:url会会被忽略,所以可以不写,这个参数是为了安全考虑,postMessage()只会将message传递给指定窗口,当然如果愿意可以将参数设置为‘*’,这样可以传递给任意窗口,如果要指定和当前窗口同源的话设置为“/”;
例子:
在http://www.abc.com/index.html页面中
<div style="width:200px;float:left; margin-right:200px;border:solid 1px #333;">
<div id="color">Frame Color</div>
</div>
<div>
<iframe id="child" src="http://lsLib.com/lsLib.html"></iframe>
</div>
在http://www.abc.com/index.html页面中向http://lsLib.com/lsLib.html传递数据,这两个页面不同域,想要通信,可以使用postMessage();
在发送信息页面这端(http://www.abc.com/index.html):
使用postMessage();
window.οnlοad=function(){
window.frames[0].postMessage('getcolor','http://lslib.com');
}
在另一域的页面中,我们需要对发过来的信息进行接收:
window.addEventListener('message',function(e){
if(e.source!=window.parent) return;
var color=container.style.backgroundColor;
window.parent.postMessage(color,'*');
},false);