【问题标题】:Getting around same origin policy in javascript without server side scripts在没有服务器端脚本的情况下绕过 javascript 中的同源策略
【发布时间】:2011-01-05 05:44:16
【问题描述】:

我的环境实际上不允许服务器端脚本(很难在服务器上“安装”脚本)。我尝试使用 iframe 来违反 javascript 的同源策略;然而,这并没有奏效。还有其他我不知道的解决方法吗?

谢谢!

【问题讨论】:

  • 什么浏览器?你到底是怎么尝试的?邮政编码?
  • JSON-P 是最简单的解决方案,也是唯一不需要浏览器插件(如 Flash)的解决方案(AFAIK)。这确实需要运行不同源站点的任何人的合作。
  • 这个问题可能是这里被问得最多的问题了!搜索会带来 许多 个答案。您需要控制两个域上的脚本和页面(如果您无法编辑两个域上的内容,您将无法执行此操作),并且需要使用诸如 easyxdm.net 之类的框架或搜索用于“跨域消息通信”。 HTML5 规范确实有一个postMessage 方法,但是如果你仅仅依赖它,它在大多数浏览器中都不起作用,所以你需要回退到一个旧的“hack”方法——为什么不让一个框架来替你处理这个?
  • Sooo 作为更新。我发现:来自ajaxian.com/archives/using-yql-as-a-proxy-for-cross-domain-ajax 的 YQL 它会抓取您指定的任何 url 并将其包装在 JSON 中并返回。然后,您可以使用 jquery 的 getJSON 函数来获取该 url。它似乎正在工作:)!
  • 只需使用easyXDM,它是一个只需很少编码即可实现跨域消息传递的库,并且不需要任何服务器组件。

标签: javascript cross-domain same-origin-policy


【解决方案1】:

正如David Dorward 提到的,JSON-P 是最简单最快的;但是,还有另一个技巧,特别是使用两个 iframe。

两个在不使用 JSONP 的情况下解决此问题,您可以执行以下操作。此技术假定您对父页面具有某种开发访问权限。

两个域/站点上有三个页面。

  1. 父页面
  2. 内容页面
  3. 跨域通信页面(又名“xdcomm”)

父页面和 xdcomm 页面托管在同一个域上,内容页面托管在任何其他域上。内容页面作为 iframe 嵌入到父页面中,xdcomm 页面作为隐藏 iframe 嵌入到内容页面中。

xdcomm 页面包含一个非常简单的脚本,它检测查询字符串中的 GET 参数,解析该字符串中的 methodargs 变量(其中 args 是 JSON 编码的字符串),然后执行指定的方法在父页面中使用指定的参数。一个例子可以是seen here(查看源代码)。

尽管 JavaScript 的同源策略限制一个域上的代码访问另一个域的代码,但域是否相互嵌套(域 A、嵌套在域 B、嵌套在域 A)并不重要。

因此,简而言之,内容页面通过 xdcomm 页面将消息发送到父页面,方法是将 iframe 的源更改为http://domaina.com/xdcomm.html?src=foo&args=[1,2,3,4] 之类的内容。这相当于在父页面中执行foo(1,2,3,4)

另外,要知道已经有一些库可以帮助您解决这个问题,例如easyxdm。我在这里解释的是他们使用的一种技术的基础,虽然它可能不那么花哨,但它肯定是一个功能齐全且轻量级的实现。

【讨论】:

  • 其实是的,请告诉我!! :)
  • 我实际上要写一些相当完整的东西。稍后再回来查看。
  • 您能否提供工作示例,或将我链接到 1 个已经存在的? - (我会非常高兴)。我对纯 JavaScript 解决方案感兴趣,没有库、脚本或类似的东西。我试着自己找例子。可悲的是,我发现的最好的是这个解决方案 - ternarylabs.com/2011/03/27/… - 但我看不到如何使用它来从嵌入式iframe 中使用的外部服务器挖掘数据。如果无法满足我的要求,请告诉我,我会创建一个新问题。
  • @Justin Johnson,不,但这无济于事 - 我无法修改/添加助手(或其他)到我想连接的外部服务器,所以 iframe 没用.我设法用jsonp 解决了我的问题,这是允许的。
  • easyXDM 对我来说似乎并不容易。这是一个相当沉重的库,看着它的代码文件夹就头晕目眩,找不到“从跨域获取json”的简单示例,它似乎最终依赖于Flash。我最终使用 YQL,如下所述。
【解决方案2】:

希望不会,因为这将是一个安全漏洞! :)

但是,如果您的两个站点都是同一域中的子域,那么 document.domain 可能会有所帮助。

【讨论】:

  • 因此,例如,如果我的域是 awesome.yahoo.com,并且我正在尝试访问 bob.yahoo.com,我可以将 document.domain 设置为 yahoo.com,然后就可以访问了bob.yahoo.com?
  • 我也意识到这是一个安全漏洞;但是,我希望有一个洞哈哈哈。如果您考虑使用代理可以解决问题。我不明白为什么在不允许直接访问文件时允许使用代理。另外我听说 html 5 有一些属性也允许跨域的东西。
  • 代理不会将用户 cookie 或任何其他身份验证数据发送到远程站点 - 因为它不知道它们是什么。它只能获取网站无论如何都可以获得的数据。它不能冒充用户。正在开发一个权限系统,以便 XHR 可以访问远程站点,目前浏览器支持很弱。
  • 啊,有道理。我没有考虑过那种东西。
猜你喜欢
  • 2011-03-29
  • 2014-12-17
  • 1970-01-01
  • 2014-03-17
  • 2012-12-30
  • 2011-12-18
  • 1970-01-01
  • 2014-12-12
  • 2011-02-14
相关资源
最近更新 更多