`

js跨域问题小结

    博客分类:
  • web
阅读更多
javascript出于安全方面的考虑,是不允许跨域调用其他页面的对象的。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。没有记错的话前三届D2论坛上每次都有人提这个东西,这里把涉及到跨域的一些问题简单地整理一下:

首先什么是跨域,简单地理解就是因为javascript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。更详细的说明可以看下表:

URL 说明 是否允许通信
http://www.f2e.me/lab/a.js
http://www.f2e.me/script/b.js 同一域名下不同文件夹 允许
http://www.f2e.me/a.js
http://www.f2e.me/b.js 同一域名下 允许
http://www.f2e.me:8000/a.js
http://www.f2e.me/b.js 同一域名,不同端口 不允许
http://www.f2e.me/a.js
https://www.f2e.me/b.js 同一域名,不同协议 不允许
http://www.f2e.me/a.js
http://70.32.92.74/b.js 域名和域名对应ip 不允许
http://www.f2e.me/a.js
http://script.f2e.me/b.js 主域相同,子域不同 不允许
http://www.space007.com/a.js
http://www.f2e.me/b.js 不同域名 不允许

特别注意两点:

第一,如果是协议和端口造成的跨域问题“前台”是无能为力的,

第二:在跨域问题上,域仅仅是通过URL的首部来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。

接下来简单地总结一下在“前台”一般处理跨域的办法,后台proxy这种方案牵涉到后台的配置,这里就不阐述了,有兴趣的可以看看YAHOO的这篇文章: 
JavaScript: Use a Web Proxy for Cross-Domain XMLHttpRequest Calls。

1、document.domain+iframe的设置
对于主域相同而子域不同的例子,可以通过设置document.domain的办法来解决。具体的做法是可以在http://www.f2e.me/a.html和http://script.f2e.me/b.html两个文件中分别加上document.domain = ‘f2e.me’;然后通过a.html文件中创建一个iframe,去控制iframe的contentDocument,这样两个js文件之间就可以“交互”了。当然这种办法只能解决主域相同而二级域名不同的情况,如果你异想天开的把script.f2e.me的domian设为alibaba.com那显然是会报错地!代码如下:
www.f2e.me上的a.html

        document.domain = 'f2e.me';
var ifr = document.createElement('iframe');
ifr.src = 'http://script.f2e.me/b.html';
ifr.style.display = 'none';
document.body.appendChild(ifr);
ifr.onload = function(){
var x = ifr.contentDocument;
alert(x.getElementsByTagName("h1")[0].childNodes[0].nodeValue);
}
script.f2e.me上的b.html

document.domain = 'f2e.me';
2、动态创建script
虽然浏览器默认禁止了跨域访问,但并不禁止在页面中引用其他域的JS文件,并可以自由执行引入的JS文件中的function,根据这一点,可以方便地通过创建script节点的方法来实现完全跨域的通信。具体的做法可以参考yui的 Get Utility

这里判断script节点加载完毕还是蛮有意思的:ie只能通过script的readystatechange属性,Safari 3.x以上支持的是script的load事件,而firefox和oprea则要通过onload来解决。另外这种办法只能传递js类型的数据,不是很方便。以下是部分判断script加载完毕的方法。

……

// ie支持script的readystatechange属性
// IE supports the readystatechange event for script and css nodes
if (ua.ie) {
n.onreadystatechange = function() {
var rs = this.readyState;
if ("loaded" === rs || "complete" === rs) {
n.onreadystatechange = null;
f(id, url);
}
};

……

// // Safari 3.x supports the load event for script nodes (DOM2)

……

n.addEventListener("load", function() {
f(id, url);
});

……

// FireFox and Opera support onload (but not DOM2 in FF) handlers for
// script nodes.  Opera, but not FF, supports the onload event for link
// nodes.
} else {
n.onload = function() {
f(id, url);
};
}
3、利用iframe和location.hash
这个办法比较绕,但是可以解决完全跨域情况下的脚步置换问题。原理是利用location.hash来进行传值。在url: http://f2e.me#helloword中的‘#helloworld’就是location.hash,改变hash并不会导致页面刷新,所以可以利用hash值来进行数据传递,当然数据容量是有限的。假设域名f2e.me下的文件cs1.html要和space007.com域名下的cs2.html传递信息,cs1.html首先创建自动创建一个隐藏的iframe,iframe的src指向space007.com域名下的cs2.html页面,这时的hash值可以做参数传递用。cs2.html响应请求后再将通过修改cs1.html的hash值来传递数据。(因为ie不允许修改parent.location.hash的值,所以要借助于f2e.me域名下的一个代理iframe)。同时在cs1.html上加一个定时器,隔一段时间来判断location.hash的值有没有变化,一点有变化则获取获取hash值。代码如下:
先是f2e.me下的文件cs1.html文件:

function startRequest(){
var ifr = document.createElement('iframe');
ifr.style.display = 'none';
ifr.src = 'http://www.space007.com/lab/cscript/cs2.html#paramdo';
document.body.appendChild(ifr);
}

function checkHash() {
try {
var data = location.hash ? location.hash.substring(1):'';
if(console.log){
console.log('Now the data is '+data);
}
}catch(e){};
}
setInterval(checkHash, 2000);
space007.com域名下的cs2.html:

(function(){
//模拟一个简单的参数处理操作
switch(location.hash){
case '#paramdo':
callBack();
break;
case '#paramset':
//do something……
break;
}

function callBack(){
try {
            parent.location.hash = 'somedata';
        } catch (e) {
        //ie的安全机制无法修改parent.location.hash,所以要利用一个中间在space007域下的代理iframe
        var ifrproxy = document.createElement('iframe');
        ifrproxy.style.display = 'none';
        ifrproxy.src = 'http://f2e.me/test/cscript/cs3.html#somedata';
        document.body.appendChild(ifrproxy);
        }
}
})();
f2e.me下的域名cs3.html

//因为parent.parent和自身属于同一个域,所以ie下可以改变其location.hash的值
parent.parent.location.hash = self.location.hash.substring(1);
实例请点击  hash实现完全跨域
当然这样做也存在很多缺点,诸如数据直接暴露在了url中,数据容量和类型都有限等……

4、利用flash
这是从YUI3的IO组件中看到的办法,具体可见:http://developer.yahoo.com/yui/3/io/
flash这个方案不是很明白,各位自己慢慢琢磨了,呵呵。你可以看在Adobe Developer Connection看到更多的跨域代理文件规范:
ross-Domain Policy File Specifications.
HTTP Headers Blacklist.
分享到:
评论

相关推荐

    js 跨域和ajax 跨域问题小结

    js 要跨域的话,可以用: [removed][removed]这样是可以从别的网站里面读取出数据的。 关键是看你灵不灵活,会不会用了。 ajax要跨域的话,可以用服务器去别的网站取内容,如asp.net的: 代码如下:public string ...

    js中各种跨域问题实战小结

    这里更加细致详细的总结了为什么要跨域:javascript跨域之什么是跨域?为什么跨域?于是当我们想某些特定的功能的时候,实现合理的跨域请求就显得比较重要了。我努力通过自己动手,自己模拟环境来切实的尝试跨域是...

    AJax与Jsonp跨域访问问题小结

    本文给大家汇总介绍了JavaScript的AJax,JQuery的AJax以及利用jsonp实现跨域访问的问题,非常的细致全面,有需要的小伙伴可以参考下。

    详解js的延迟对象、跨域、模板引擎、弹出层、AJAX【附实例下载】

    3.5、小结 四、弹出层 五、模板引擎 5.1、Hello World 5.2、方法 5.3、与AJAX结合应用 六、示例下载 一、AJAX示例 AJAX全称为“Asynchronous JavaScript And XML”(异步JavaScript和XML) 是指一种创建交互式网

    JavaScript权威指南(第6版)

    5.8 JavaScript语句小结 第6章 对象 6.1 创建对象 6.2 属性的查询和设置 6.3 删除属性 6.4 检测属性 6.5 枚举属性 6.6 属性getter和setter 6.7 属性的特性 6.8 对象的三个属性 6.9 序列化对象 6.10 对象方法 第7章 ...

    简单介绍jsonp 使用小结

    同源策略,它是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript 的浏览器都会使用这个策略。 首先:jsonp是json用来跨域的一个东西。 原理是通过script标签的跨域特性来绕过同源策略。 经过测试实验...

    Ext Js权威指南(.zip.001

    1.6 本章小结 / 33 .第2章 从“hello world”开始 / 34 2.1 获取ext js 4 / 34 2.2 配置使用ext js库 / 35 2.3 编写“hello world”程序 / 37 2.4 关于ext.onready / 38 2.5 关于ext.blank_image_url / 40 ...

    JavaScript权威指南(第6版)(中文版)

    5.8 JavaScript语句小结 第6章 对象 6.1 创建对象 6.2 属性的查询和设置 6.3 删除属性 6.4 检测属性 6.5 枚举属性 6.6 属性getter和setter 6.7 属性的特性 6.8 对象的三个属性 6.9 序列化对象 6.10 对象方法 第7章 ...

    JavaScript权威指南(第6版)中文文字版

    5.8 javascript语句小结 116 第6章 对象 118 6.1 创建对象 120 6.2 属性的查询和设置 123 6.3 删除属性 127 6.4 检测属性 128 6.5 枚举属性 130 6.6 属性getter和setter 132 6.7 属性的特性 134 6.8 对象的三个属性 ...

    白帽子讲浏览器安全.钱文祥(带详细书签).pdf

    1.8 本章小结 12 2 浏览器中常见的安全概念 13 2.1 URL 13 2.1.1 URL的标准形式 15 2.1.2 IRI 16 2.1.3 URL的“可视化”问题——字形欺骗钓鱼攻击 18 2.1.4 国际化域名字形欺骗攻击 19 2.1.5 自纠错与Unicode...

    ASP.NET AJAX实战源码

    第4章 Ajax服务器扩展剖析 86 4.1 ASP.NET开发人员的Ajax 86 4.2 改进原有ASP.NET网站 87 4.2.1 一个示例ASP.NET网站 88 4.2.2 配置现有的ASP.NET网站 88 4.3 ScriptManager: Ajax页面的大脑 90 ...5.5 小结 145

    segment:分散的知识点

    segment Scattered knowledge points here. Maybe you can find something useful. 最近更新 JavaScript 新旧替换 工作流 Canvas Canvas 绘制 1 px 直线模糊(非高清屏)的问题 ...CSS 浮动 float 小结 Object.obser

    JavaScript权威指南(第六版) 清晰-完整

    5.8 JavaScript语句小结 第6章 对象 6.1 创建对象 6.2 属性的查询和设置 6.3 删除属性 6.4 检测属性 6.5 枚举属性 6.6 属性getter和setter 6.7 属性的特性 6.8 对象的三个属性 6.9 序列化对象 6.10 对象方法 第7章 ...

    Flex企业应用开发实战源代码

    1.5 小结 20 第2章 Flex企业应用开发基础 21 2.1 MXML语言 21 2.1.1 用MXML表示ActionScript对象 22 2.1.2 查看由MXML文件所翻译的ActionScript代码 24 2.1.3 IMXMLObject接口 25 2.2 客户端保持状态 28 2.3 ...

Global site tag (gtag.js) - Google Analytics