billfeller.github.io
billfeller.github.io copied to clipboard
通过window.name+iframe实现跨域解决方案
通过 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>
此时,刷新 target-name.html , window.name 不会改变。
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