概述和原始问题
window.name 是一个有趣的东西。MDN的描述暗示了最初的意图:
窗口的名称主要用于设置超链接和表单的目标。窗口不需要具有名称。
所以,这意味着我们可以在该窗口中打开控制台,并编写:
var win = window.open('http://google.com', 'el goog');
...然后让它通过弹出窗口拦截器,这应该会在一个名为“el goog”的窗口中打开google.com。由于同源策略,我无法访问win的name属性,但是如果我在新窗口中打开控制台并输入name,我将得到“el goog”的结果。如果我将窗口发送回我打开它的域(在本例中为stackoverflow.com),我可以获取name属性,并且它没有改变。
win.location.replace(location.href);
win.name; // "el goog"
这意味着我们可以通过设置窗口的
name
属性来拥有一种跨域会话存储方式。如果在将窗口发送回原始域之前,google.com已经更改了
window.name
的值,那么我们将看到新值而不是"el goog"。这可以用作跨域数据传输,类似于JSONP或CORS的实用工具。我搜索了一下以找到更多信息,显然dojo 认为它是合法的作为一种传输方式。然而,这并没有完全让我放心。所以我的问题是,是否有任何知名网站使用
window.name
作为数据传输?我认为这应该很容易发现,因为他们的文档会说类似于"将'callback'添加到查询字符串中用于JSONP,或者添加'whatever'用于window.name,"但我从未见过这样的内容。有人真的在实际应用中发现了吗?
备选问题
可能没有人真正使用这种技术;如果是这样的话(正如Rob W所指出的),上面的问题就无法回答。因此,我备选的问题是,这种方法有什么问题?这可能有助于解释为什么它并没有被广泛采用。
在我看来,这种方法至少有两个优点,相比JSONP而言:
使用JSONP时,您需要信任来自外部源的脚本在您的域上运行。而使用
window.name
,由恶意站点包含的任何脚本都将在其自己的域上运行。使用JSONP时,无法传递大数据(任何太大而无法通过URL传递的数据),也无法进行HTTP POST。而使用
window.name
,我们可以发布任意大小的任意数据。
那么,这种方法有什么缺点呢?
示例实现
这是一个非常简单的客户端实现示例。它只处理GET请求,不处理POST请求。
function fetchData(url, callback) {
var frame = document.createElement('iframe');
frame.onload = function() {
frame.onload = function() {
callback(frame.contentWindow.name);
frame.parentNode.removeChild(frame);
}
frame.src = 'about:blank';
}
frame.src = url;
document.body.appendChild(frame);
}
// using it
fetchData('http://somehost.com/api?foo=bar', function(response) {
console.log(response);
});
我已经设置了一个fiddle来测试它 这里。 它使用这个脚本作为测试服务器。
这是一个稍微长一点的例子,可以进行POST请求:http://jsfiddle.net/n9Wnx/2/
摘要
据我所知,window.name
并没有成为数据传输的主流方式。我想知道我的看法是否准确(因此提出了这个问题),如果是的话,我想知道为什么会这样。我列出了一些window.name
似乎比JSONP具有的优点。有人能否找出一些可能导致阻止采用此技术的缺点?
更重要的是,有人能给我一个充分的理由,说明我不应该使用window.name
作为数据传输吗?