概述和原始问题
window.name是一个有趣的野兽。MDN 的描述暗示了最初的意图:
窗口的名称主要用于设置超链接和表单的目标。Windows 不需要有名称。
所以,这意味着我们可以在这个窗口中打开控制台,然后写:
var win = window.open('http://google.com', 'el goog');
...然后让它通过弹出窗口阻止程序,它应该在名为“el goog”的窗口中打开 google.com。由于同源策略,我无法访问 的name
属性,但如果我在新窗口中打开控制台并键入,我会得到.win
name
"el goog"
如果我将窗口发送回我打开它的域(在本例中为 stackoverflow.com),我可以获得该name
属性,并且它没有改变。
win.location.replace(location.href);
win.name; // "el goog"
name
这意味着我们可以通过设置窗口的属性来拥有一种跨域会话存储。
如果 google.com在窗口被发送回原始域之前更改了值window.name
,我们将看到新值而不是“el goog”。这可以用作跨域数据传输,类似于 JSONP 或 CORS 的实用程序。
我做了一些搜索以试图找到更多信息,显然道场认为它作为一种交通工具是合法的。不过,不知何故,这并不能完全让我放心。所以我的问题是,是否有任何信誉良好的网站window.name
用作数据传输?我认为这很容易被发现,因为他们的文档会说“在 JSONP 的查询字符串中添加 'callback',或者为 window.name 添加 'whatever' ”,但我从未见过这样的事情。真的有人在野外发现过这个吗?
替代问题
可能没有人真正使用这种技术。如果这是真的,那么(正如 Rob W 指出的那样)上面的问题是无法回答的。所以,我的另一个问题是,这种方法有什么问题?这可能有助于解释为什么它没有真正被采用。
正如我所看到的,这种方法比 JSONP 至少有两个好处。
使用 JSONP,您可以信任来自外国的脚本在您的域上运行。使用
window.name
,恶意站点包含的任何脚本都将在其自己的域上运行。使用 JSONP,无法传递大数据(对于 URL 来说太大的数据),也无法进行 HTTP POST。有了
window.name
,我们可以发布任意大小的任意数据。
有什么缺点?
示例实现
这是一个非常简单的客户端实现示例。这不处理 POST 请求,只处理 GET。
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);
});
我已经设置了一个小提琴来测试它。它使用这个脚本作为测试服务器。
这是一个稍长的示例,可以发出 POST 请求:http: //jsfiddle.net/n9Wnx/2/
概括
据我所知,window.name
还没有流行起来作为数据传输。我想知道我的看法是否准确(因此是原始问题),如果是,我想知道为什么会这样。我列出了一些window.name
似乎优于 JSONP 的优点。任何人都可以找出一些可能导致阻止采用这种技术的缺点吗?
更重要的是,谁能给我一个充分的理由为什么我不应该将winow.name
其用作数据传输?