深入理解AJAX系列第四篇--跨域问题

来源:互联网 发布:华润儿童漆怎么样知乎 编辑:程序博客网 时间:2024/06/08 08:29

我们先了解一下域名地址的组成:http:// www . google : 8080 / script/jquery.js

  http:// (协议号)

  www (子域名)

  google (主域名)

   8080 (端口号)

  script/jquery.js (请求的地址)

  • 当协议、子域名、主域名、端口号中任意一各不相同时,都算不同的“域”。
  • 不同的域之间相互请求资源,就叫“跨域”。
    但是我们有时候需要使用AJAX请求其他域名下的请求,但是会出现拒绝访问的情况,这是因为基于安全的考虑,AJAX只能访问本地的资源,而不能跨域访问。
    处理跨域的方法1 – 代理
    这种方式是通过后台(ASP、PHP、JAVA、ASP.NET)获取其他域名下的内容,然后再把获得内容返回到前端,这样因为在同一个域名下,所以就不会出现跨域的问题。
    比如在A(www.a.com/sever.php)和B(www.b.com/sever.php)各有一个服务器,A的后端(www.a.com/sever.php)直接访问B的服务,然后把获取的响应值返回给前端。也就是A的服务在后台做了一个代理,前端只需要访问A的服务器也就相当与访问了B的服务器。
    处理跨域的方法2 – JSONP(只支持GET请求)
    这种方式的原理是动态添加一个
function jsonpCallback(result) {       alert(result.msg);   }  var JSONP=document.createElement("script");  JSONP.type="text/javascript";  JSONP.src="http://crossdomain.com/services.php?callback=jsonpCallback";  document.getElementsByTagName("head")[0].appendChild(JSONP);  

JSONP优点
不受同源策略的限制,兼容性更好,在古老的浏览器中运行的很好,不需要XMLHttpRequest支持,请求完毕后可以通过callback返回结果。
缺点
1.不支持post请求方式,只支持get方法。
2.安全性。JOSNP是从其他域中加载代码执行,如果别的域存在安全性问题,则此时很可能收到恶意代码的攻击。此时只能放弃JSONP调用
3.要确定请求是否失败并不容易,必须使用计时器检测指定事件内是否收到响应。
处理跨域的方法3 –修改document.domain来跨子域
比如,有一个页面,它的地址是http://www.example.com/a.html , 在这个页面里面有一个iframe,它的src是
http://example.com/b.html, 很显然,这个页面与它里面的iframe框架是不同域的,所以我们是无法通过在页面中书写js代码来获
取iframe中的东西的:这个时候,document.domain就可以派上用场了,我们只要把
http://www.example.com/a.html 和 http://example.com/b.html这两个页面的document.domain都设成相同的域名就可以了。但要
注意的是,document.domain的设置是有限制的,我们只能把document.domain设置成自身或更高一级的父域,且主域必须相同。注
意:修改document.domain的方法只适用于不同子域的框架间的交互。
处理跨域的方法4 –使用HTML5的window.postMessage方法
window.postMessage(message,targetOrigin) 方法是Html5新引进的特性,可以使用它来向其它的window对象发送消息,无论这个
window对象是属于同源或不同源,目前IE8+、FireFox、Chrome、Opera等浏览器都已经支持window.postMessage方法。
调用postMessage方法的window对象是指要接收消息的那一个window对象,该方法的第一个参数message为要发送的消息,类 型只能为字符串;第二个参数targetOrigin用来限定接收消息的那个window对象所在的域,如果不想限定域,可以使用通配符 * ;
使用postMessage来跨域传送数据还是比较直观和方便的,但是缺点是IE6、IE7、IE8不支持,所以用不用还得根据实际需要来决定。
处理跨域的方法5 –图像Ping
图像Ping是与服务器进行简单、单向的跨域通信的一种方式。请求的数据是通过查询字符串形式发送的,而响应可以是任意内容,但通常是图像或204响应。

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

图像ping常用于跟踪用户点击页面或动态广告曝光次数。
缺点:1.只能发送GET请求
2.无法访问服务器的响应文本
处理跨域的方法6 –window.name
window对象有个name属性,该属性有个特征:即在一个窗口(window)的生命周期内,窗口载入的所有的页面都是共享一个 window.name的,每个页面对window.name都有读写的权限,window.name是持久存在一个窗口载入过的所有页面中的,并不会因 新页面的载入而进行重置;
比如:有一个页面a.html,它里面有这样的代码:
这里写图片描述
再看看b.html页面的代码:
这里写图片描述
a.html页面载入后3秒,跳转到了b.html页面,结果为:
这里写图片描述