billfeller.github.io icon indicating copy to clipboard operation
billfeller.github.io copied to clipboard

通过window.name+iframe实现跨域解决方案

Open billfeller opened this issue 7 years ago • 0 comments

通过 window.name+iframe 实现跨域解决方案

原理

问题:如何通过 window.name+iframe 在 a.com/index.html 获取 b.com 下的资源

通过 http://a.com/index.html 设置 iframe.src="http://b.com/proxy.html" 获取跨域资源值,将其赋值保存于 window.name 中,然后设置 iframe.src = "http://a.com/blank.html" 指向 a.com 下的空白页,由于刷新 iframe 页面并不会改变 iframe 下 window.name 属性值,所以可以在 a.com/index.html 访问同源的 blank.html 窗口name属性值 iframe.concentWindow.name 获取跨域资源。

1. window.name 保存跨域资源

引用自:https://developer.mozilla.org/en-US/docs/Web/API/Window/name

The name of the window is used primarily for setting targets for hyperlinks and forms. Windows do not need to have names.

It has also been used in some frameworks for providing cross-domain messaging (e.g., SessionVars and Dojo's dojox.io.windowName) as a more secure alternative to JSONP. Modern web applications hosting sensitive data should however not rely on window.name for cross-domain messaging but instead rather utilize the postMessage API.

Don't set the value to something unstring since its get method will call the toString method.

window.name 即窗口名字,可以通过 window.name="name" 手动赋值,也可以通过 <a target="" /> <form target="" /> 设置。

示例代码如下:

index.html

<!DOCTYPE html>
<html>
<head>
    <title>window.name+iframe跨域通信方案</title>
</head>
<body>
    <!-- 1. window.name 保存跨域资源 -->
    <a href="target-name.html" target="custom-target">window.name属性值是通过target属性值来初始化。</a>
</body>
</html>

target-name.html

<!DOCTYPE html>
<html>
<head>
    <title></title>
</head>
<body>
<script type="text/javascript">
    alert(window.name); // 获取窗口名字
</script>
</body>
</html>

image

image

此时,刷新 target-name.html , window.name 不会改变。

image

2. 通过 iframe.contontWindow.name 访问同源iframe页面下的window.name属性值

引用自:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe

Scripts trying to access a frame's content are subject to the same-origin policy, and cannot access most of the properties in the other window object if it was loaded from a different domain. This also applies to a script inside a frame trying to access its parent window. Cross-domain communication can still be achieved with Window.postMessage().

index.html

<!DOCTYPE html>
<html>
<head>
    <title>window.name+iframe跨域通信方案</title>
</head>
<body>
    <!-- 2. 通过 iframe.contontWindow.name 访问同源iframe页面下的window.name属性值 -->
    <iframe id="J_iframe" src="origin.html" onload="load(this);" style="display: none;"></iframe>
    <script type="text/javascript">
        function load(iframe) {
            console.log(iframe.contentWindow.name);
        }
    </script>
</body>
</html>

origin.html

<!DOCTYPE html>
<html>
<head>
    <title>origin.html</title>
</head>
<body>
<script type="text/javascript">
    window.name = "testtest";
</script>
</body>
</html>

由此,参考 respond.js 实现的通过 window.name+iframe 实现跨域通信。

详细代码参考 https://github.com/scottjehl/Respond/tree/master/cross-domain

参考阅读

  1. media query ie8- 兼容实现总结
  2. window.name实现的跨域数据传输
  3. window.name(MDN)

billfeller avatar Sep 08 '17 13:09 billfeller