`
javafw
  • 浏览: 13388 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

js跨域的解决方案

    博客分类:
  • js
阅读更多

在客户端编程语言中,如javascript和ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同 源策略规定跨域之间的脚本是隔离的,一个域的脚本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?

 

同源策略

在客户端编程语言中,如javascript和 ActionScript,同源策略是一个很重要的安全理念,它在保证数据的安全性方面有着重要的意义。同源策略规定跨域之间的脚本是隔离的,一个域的脚 本不能访问和操作另外一个域的绝大部分属性和方法。那么什么叫相同域,什么叫不同的域呢?当两个域具有相同的协议(如http), 相同的端口(如80),相同的host(如www.example.org),那么我们就可以认为它们是相同的域。比如 http://www.example.org/index.html和http://www.example.org/sub/index.html是 同域,而http://www.example.org, https://www.example.org, http://www.example.org:8080, http://sub.example.org中的任何两个都将构成跨域。同源策略还应该对一些特殊情况做处理,比如限制file协议下脚本的访问权限。 本地的HTML文件在浏览器中是通过file协议打开的,如果脚本能通过file协议访问到硬盘上其它任意文件,就会出现安全隐患,目前IE8还有这样的 隐患。

受到同源策略的影响,跨域资源共享就会受到制约。但是随着人们的实践和浏览器的进步,目前在跨域请求的技巧上,有很多宝贵经验的沉淀和积累。这里我把跨域资源共享分成两种,一种是单向的数据请求,还有一种是双向的消息通信。接下来我将罗列出常见的一些跨域方式,以下跨域实例的源代码可以从这里获得

单向跨域

JSONP

JSONP (JSON with Padding)是一个简单高效的跨域方式,HTML中的script标签可以加载并执行其他域的javascript,于是我们可以通过script标记来动态加载其他域的资源。 例如我要从域A的页面pageA加载域B的数据,那么在域B的页面pageB中我以JavaScript的形式声明pageA需要的数据,然后在 pageA中用script标签把pageB加载进来,那么pageB中的脚本就会得以执行。JSONP在此基础上加入了回调函数,pageB加载完之后 会执行pageA中定义的函数,所需要的数据会以参数的形式传递给该函数。JSONP易于实现,但是也会存在一些安全隐患,如果第三方的脚本随意地执行, 那么它就可以篡改页面内容,截获敏感数据。但是在受信任的双方传递数据,JSONP是非常合适的选择。

flash URLLoader

flash有自己的一套安全策略,服务器可以通过crossdomain.xml文件来声明能被哪些域的SWF文件访问,SWF也可以通过API来确定自身能被哪些域的SWF加载。当跨域访问资源时,例如从域www.a.com请求域www.b.com上的数据,我们可以借助flash来 发送HTTP请求。首先,修改域www.b.com上的crossdomain.xml(一般存放在根目录,如果没有需要手动创建) ,把www.a.com加入到白名单。其次,通过Flash URLLoader发送HTTP请求,最后,通过Flash API把响应结果传递给JavaScript。Flash URLLoader是一种很普遍的跨域解决方案,不过需要支持iOS的话,这个方案就无能为力了。

Access Control

Access Control是比较超越的跨域方式,目前只在很少的浏览器中得以支持,这些浏览器可以发送一个跨域的HTTP请求(Firefox, Google Chrome等通过XMLHTTPRequest实现,IE8下通过XDomainRequest实现),请求的响应必须包含一个Access- Control-Allow-Origin的HTTP响应头,该响应头声明了请求域的可访问权限。例如www.a.com对www.b.com下的 asset.php发送了一个跨域的HTTP请求,那么asset.php必须加入如下的响应头:

header("Access-Control-Allow-Origin: http://www.a.com");

window.name

window 对象的name属性是一个很特别的属性,当该window的location变化,然后重新加载,它的name属性可以依然保持不变。那么我们可以在页面 A中用iframe加载其他域的页面B,而页面B中用JavaScript把需要传递的数据赋值给window.name,iframe加载完成之后,页 面A修改iframe的地址,将其变成同域的一个地址,然后就可以读出window.name的值了。这个方式非常适合单向的数据请求,而且协议简单、安 全。不会像JSONP那样不做限制地执行外部脚本。

server proxy

在数据提供方没有提供对JSONP协议或者 window.name协议的支持,也没有对其它域开放访问权限时,我们可以通过server proxy的方式来抓取数据。例如当www.a.com域下的页面需要请求www.b.com下的资源文件asset.txt时,直接发送一个指向 www.b.com/asset.txt的Ajax请求肯定是会被浏览器阻止。这时,我们在www.a.com下配一个代理,然后把Ajax请求绑定到这个代理路径下,例如www.a.com/proxy/, 然后这个代理发送HTTP请求访问www.b.com下的asset.txt,跨域的HTTP请求是在服务器端进行的,客户端并没有产生跨域的Ajax请求。这个跨域方式不需要和目标资源签订协议,带有侵略性,另外需要注意的是实践中应该对这个代理实施一定程度的保护,比如限制他人使用或者使用频率。

双向跨域

document.domain

通 过修改document的domain属性,我们可以在域和子域或者不同的子域之间通信。同域策略认为域和子域隶属于不同的域,比如www.a.com和 sub.a.com是不同的域,这时,我们无法在www.a.com下的页面中调用sub.a.com中定义的JavaScript方法。但是当我们把它 们document的domain属性都修改为a.com,浏览器就会认为它们处于同一个域下,那么我们就可以互相调用对方的method来通信了。

FIM – Fragment Identitier Messaging

不 同的域之间,JavaScript只能做很有限的访问和操作,其实我们利用这些有限的访问权限就可以达到跨域通信的目的了。FIM (Fragment Identitier Messaging)就是在这个大前提下被发明的。父窗口可以对iframe进行URL读写,iframe也可以读写父窗口的URL,URL有一部分被称 为frag,就是#号及其后面的字符,它一般用于浏览器锚点定位,Server端并不关心这部分,应该说HTTP请求过程中不会携带frag,所以这部分 的修改不会产生HTTP请求,但是会产生浏览器历史记录。FIM的原理就是改变URL的frag部分来进行双向通信。每个window通过改变其他 window的location来发送消息,并通过监听自己的URL的变化来接收消息。这个方式的通信会造成一些不必要的浏览器历史记录,而且有些浏览器 不支持onhashchange事件,需要轮询来获知URL的改变,最后,URL在浏览器下有长度限制,这个制约了每次传送的数据量。

Flash LocalConnection

页 面上的双向通信也可以通过Flash来解决,Flash API中有LocalConnection这个类,该类允许两个SWF之间通过进程通信,这时SWF可以播放在独立的Flash Player或者AIR中,也可以嵌在HTML页面或者是PDF中。遵循这个通信原则,我们可以在不同域的HTML页面各自嵌套一个SWF来达到相互传递 数据的目的了。SWF通过LocalConnection交换数据是很快的,但是每次的数据量有40kb的大小限制。用这种方式来跨域通信过于复杂,而且 需要了2个SWF文件,实用性不强。

window.postMessage

window.postMessage是HTML5定义的一个很新的方法,这个方法可以很方便地跨window通信。由于它是一个很新的方法,所以在很旧和比较旧的浏览器中都无法使用。

Cross Frame

Cross Frame是FIM的一个变种,它借助了一个空白的iframe,不会产生多余的浏览器历史记录,也不需要轮询URL的改变,在可用性和性能上都做了很大 的改观。它的基本原理大致是这样的,假设在域www.a.com上有页面A.html和一个空白代理页面proxyA.html, 另一个域www.b.com上有个页面B.html和一个空白代理页面proxyB.html,A.html需要向B.html中发送消息时,页面会创建 一个隐藏的iframe, iframe的src指向proxyB.html并把message作为URL frag,由于B.html和proxyB.html是同域,所以在iframe加载完成之后,B.html可以获得iframe的URL,然后解析出 message,并移除该iframe。当B.html需要向A.html发送消息时,原理一样。Cross Frame是很好的双向通信方式,而且安全高效,但是它在Opera中无法使用,不过在Opera下面我们可以使用更简单的 window.postMessage来代替。

总结

跨域的方法很多,不同的应用场景我们都可以找到一个最合适的解决方 案。比如单向的数据请求,我们应该优先选择JSONP或者window.name,双向通信我们采取Cross Frame,在未与数据提供方没有达成通信协议的情况下我们也可以用server proxy的方式来抓取数据。

 

引自: http://www.woiweb.net/10-cross-domain-methods.html

感谢原文作者!

 

 

分享到:
评论

相关推荐

    js跨域解决方案

    1. **JSONP(JSON with Padding)**:JSONP是一种早期的跨域解决方案,它依赖于`<script>`标签不受同源策略限制的特点。通过动态创建`<script>`标签,设置其`src`属性为提供服务的服务器接口,并由服务器返回一个包裹...

    js 跨域解决方案

    本文将深入探讨JavaScript跨域问题及其解决方案,以帮助开发者理解和应对这一问题。 首先,了解同源策略是解决问题的关键。同源策略是浏览器为了保障用户数据安全而实施的一种机制,它禁止了一个源的文档或脚本获取...

    js跨域解决方案.docx

    ### js跨域解决方案 #### 一、问题描述与背景 在网页开发中,经常会遇到需要一个主页面通过`iframe`动态加载子页面的情况,并且希望根据子页面的内容自动调整`iframe`的高度,以达到视觉上的无缝对接。然而,当...

    JQuery跨域访问解决方案

    JQuery的跨域解决方案主要依赖于JSONP(JSON with Padding)技术。JSONP是一种绕过同源策略的方式,它利用HTML中的`<script>`标签没有同源策略限制的特点。当jQuery使用`dataType: 'jsonp'`时,它实际上是在做以下几...

    解决JS跨域访问IFrame的解决方案

    面对这样的问题,我们可以采用以下几种跨域解决方案: 1. **CORS(Cross-Origin Resource Sharing)**:服务器可以通过设置响应头`Access-Control-Allow-Origin`来允许特定的源进行跨域请求。例如,服务器端可以在...

    Javascript跨域访问解决方案

    JSONP是一种较早的跨域解决方案,它利用了浏览器允许`<script>`标签跨域加载资源的特性。通过动态创建`<script>`标签,并指定其`src`属性为一个返回JSON数据的函数调用,服务器将数据包裹在函数调用中返回,客户端...

    Javascript跨域和Ajax跨域解决方案

    JavaScript跨域和Ajax跨域是Web开发中常见的问题,尤其在进行前后端分离或API调用时,由于浏览器的同源策略限制,不同域名、协议或端口的资源请求会被阻止,这就是所谓的“跨域”。本文将深入探讨JavaScript和Ajax...

    arcgis api for javascript跨域处理方案

    除了资源代理,还可以使用其他跨域解决方案: - CORS(跨源资源共享):服务器端可以设置CORS头(如`Access-Control-Allow-Origin`),允许特定的源进行跨域请求。这种方法需要服务器端的支持,可能不适用于所有...

    js跨域问题解决方案.

    选择哪种跨域解决方案取决于应用场景和需求。JSONP适用于简单的GET请求,CORS是现代浏览器推荐的通用方案,代理服务器适用于复杂的后端集成,`document.domain`适用于同一顶级域名下的跨子域,`postMessage`适合页面...

    Spring 跨域解决方案官方 demo

    在现代Web开发中,跨域资源共享(CORS)是一个重要的概念,它允许...总之,Spring提供的CORS解决方案让开发者能够轻松处理跨域请求,同时保持应用的安全性。理解并熟练运用这些知识,对于构建现代化的Web应用至关重要。

    跨域访问解决方案,关于跨域访问cookie的资料

    ### 跨域访问解决方案与Cookie处理 在现代Web开发中,跨域问题一直是困扰开发者的一大难题。当浏览器出于安全考虑阻止不同源之间的数据交互时,跨域问题便产生了。为了解决这一问题,并确保在跨域场景下可以正确地...

    xmlhttp跨域解决方案

    为了解决这一问题,我们可以采用多种跨域解决方案,其中一种是通过设置代理服务器。 **一、什么是同源策略** 同源策略是浏览器为了保护用户安全而实施的一种安全策略,它规定浏览器只允许加载来自相同协议、域名和...

    JS跨域解决方案之使用CORS实现跨域

    正常使用AJAX会需要正常考虑跨域问题,所以伟大的程序员们又折腾出了一系列跨域问题的解决方案,如JSONP、flash、ifame、xhr2等等。本文给大家介绍JS跨域解决方案之使用CORS实现跨域,感兴趣的朋友参考下吧

    跨域请求解决方案源代码(JSONP,CORS)

    这个文件可能包含了创建XMLHttpRequest对象、设置请求头、处理响应等内容的JavaScript代码,用于演示如何在实际项目中应用这些跨域解决方案。开发者可以通过查看和运行这些代码来加深对JSONP和CORS的理解,并在自己...

    前端跨域解决方案

    前端跨域解决方案,jsonp和cros两种解决方式。我们发现,Web页面上调用js文件时不受是否跨域的影响,凡是拥有"src"这个属性的标签都拥有跨域的能力,比如[removed]、、<iframe>。那就是说如果要跨域访问数据,...

    MVC中跨域解决方案

    4. JSONP(JSON with Padding):这是一种早期的跨域解决方案,适用于只支持GET请求的API。它通过动态创建`<script>`标签来实现跨域请求。然而,JSONP不提供安全性,只适用于简单请求,且不支持HTTP的其他方法和头。...

    Ajax跨域访问解决方案

    JSONP是一种早期的跨域解决方案,它是通过动态创建`<script>`标签来加载数据的。因为`<script>`标签不受同源策略限制,可以通过`src`属性指向提供JSON数据的外部服务。服务端返回的数据是一个JavaScript函数调用,...

    arcgis js跨域解决策略

    在ArcGIS JavaScript API中,Esri提供了一个名为"Resource Proxy"的解决方案,即resource-proxy-master文件包所包含的内容。 Resource Proxy是一个轻量级的代理服务,它可以部署在你的.NET或Java服务器上。以下是...

    JS跨域访问解决方案总结

    JavaScript跨域访问解决方案 在Web开发中,由于浏览器的安全策略——同源策略(Same Origin Policy),不同源的脚本之间无法直接通信或访问彼此的资源。同源策略规定,只有当两个URL的协议、域名和端口都相同时,...

Global site tag (gtag.js) - Google Analytics