跨域问题--自整理
Posted jamie1032797633
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了跨域问题--自整理相关的知识,希望对你有一定的参考价值。
题目:下面关于浏览器中使用js跨域获取数据的描述,说法错误的是()
A:域名、端口相同,协议不同的,属于相同的域
B:JS可以使用jsonp进行跨域
C:通过修改document。domain来跨子域
D:使用window.name来进行跨域
答案:A
以下的同源策略是我自己整理的,不够全面,然后已经发表的博文中有一篇我觉得整理的最好的,地址是 https://segmentfault.com/a/1190000011145364
同源策略:同源策略是客户端脚本的重要的安全度量标准。最草出自Netscape navigator2.0,目的是防止某个文档或者脚本从多个不同的源装载。javascript中同源策略对于XHR的一个主要约束,它为通信设置了“相同的域,相同的端口,相同的协议”这一限制。除了被认可的跨域解决方案以外,试图访问限制以外的资源,会引发安全错误。
同源策略/SOP(same origin policy)是一种约定,是浏览器最核心也最基础的安全功能,如果缺少了同源策略,浏览器很容易受到XSS,CSFR等攻击。
同源策略限制:
1、cookie、localStorage和INdexDB无法读取
2、DOM和JS对象无法获得
3、Ajax请求不能发送
跨域解决方案:
- jsonp
- 图像ping
- document.damian + iframe
- location.hash + iframe
- window.name + iframe
- postMessage
- CORS(cross-origin resource sharing)
- nginx代理跨域
- nodejs中间件代理跨域
- websocket协议跨域
JSONP(json with padding)
说明:通过动态script元素,为src属性指定一个跨域URL。(因为<script>元素和<img>元素,都有能力不受限制从其他域加载资源)
JSONP由两部分组成:回调函数和数据。回调函数是当响应到来时应该在页面中调用的函数。回调函数的名字一般在请求中指定。而数据就是传入回调函数中的json数据。
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);
优点:简单易用。支持在浏览器和服务器之间双向通信。
缺点:一是jsonp从其他域中加载代码执行。如果其他域不安全,很可能在响应中夹带恶意代码,此时除了放弃JSONP调用之外,没有办法追究。二是要确定JSONP请求是否失败并不容易。html5中给script增加了onerror事件处理程序(目前支持的浏览器不多)。可以使用计时器检测在指定时间内是否接受到响应。
CORS(cross-origin Resource sharing,跨源资源共享):跨域解决方案。IE8通过XDomainRequest对象支持CORS,其他浏览器通过XHR对象原生支持CORS。图像Ping和JSONP是另外两种跨域通信的技术。
图像PING
说明:使用<img>元素,因为在任何网页中加载图像时,不用担心跨域不跨域。
图像ping经常用于跟踪用户点击页面或者动态广告曝光次数。
动态创建图像,使用它们的onload和onerror事件处理程序来确定是否接到了响应。
图像ping与服务器进行简单的,单向的跨域通信。请求的数据是通过查询字符串发送的,响应可以是任意内容,但通常是像素图或者204响应。通过图像ping,浏览器得不到任何具体的数据,但通过侦听load和error事件,可以知道响应是什么时候接到的。
var img = new Image();
img.onload = img.onerror = function(){
alert("Done");
}
img.src = "http://www.example.com/test?name=Nicholas";
缺点:一只能发送get请求,二是无法访问服务器的响应文本。
comet
说明:Comet是一种更高级的Ajax技术(服务器推送)。ajax是从页面向服务器请求数据,Comet是服务器向页面推送数据。
Comet有两种实现方式:长轮询和流。
短轮询是浏览器定时向服务器发送请求,看有没有更新的数据。长轮询是页面发起一个到服务器的请求,然后服务器一直保持连接打开,直到有数据可以发送。发送完数据之后,浏览器关闭连接,随机发起一个新请求。
HTTP流,不同于轮询,它在页面的整个生命周期内只使用一个HTTP连接。浏览器向服务器发送一个请求,服务器保持连接打开,然后周期性的向浏览器发送数据。
在Firefox,safari,Opera和chrome中,通过侦听readystatechange事件及检测readystate的值是否为3,就可以利用XHR对象实现HTTP流。在上述浏览器中,随着不断从服务器接受数据,readystate的值会周期性地变为3。readystate为3时,responseText属性中就会保存接收到的所有数据。此时需要比较此前接收到的数据,决定从什么位置开始取得最新的数据。
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");
});
websocket
wensocket:在一个单独的持久连接上提供全双工、双向通信。使用websocket协议。http服务器无法实现web socket,只有支持这种协议的专门服务器才能正常工作。
postMessage
说明:html5中新增的跨文档消息传递(cross-document messaging),有时候简称为XDM。
web messaging的核心是postMessage()。想当前页面的<iframe>元素或者由当前页面弹出的窗口。
postMassage(“消息”,消息接收方来自哪个域的字符串);
var iframeWindow = document.getElementById("myframe").contentWindow;
iframeWindow.postMessage("A secret","http://www.wrox.com");
接受到XDM消息是,会触发window的message事件。这个事件是以异步形式触发,因此从发送消息到接收消息可能要经过一段时间的延迟。事件对象包含三个重要信息:
1、data postMessage()的第一个参数
2、origin 发送消息的文档所在的域
3、source 发送消息的文档的window的代理。代理主要用于发送上一条消息的窗口中调用postMessage()方法。如果发送消息的窗口来自同一个域,那这个对象就是window。
EventUtil.addHandler(window, "message", function(event){
if(event.origin == "http://www.wrox.com"){
processMessage(event.data);//处理接收的数据
event.source.postMessage("received","http://p2p.wrox.com");
}
});
通过内嵌框架加载其他域的内容时,XDM是非常方便的。在混搭(mashup)和社交网络应用中,这种传递消息的方法极为常用。
以上是关于跨域问题--自整理的主要内容,如果未能解决你的问题,请参考以下文章