概述和原始问题
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的实用程序。
我做了一些搜索,试图找到更多信息,显然dojo thinks it's legit作为运输。但不知何故,这并不能完全让我放心。所以我的问题是,是否有任何信誉良好的网站使用window.name
作为数据传输?我认为它很容易被发现,因为他们的文档会对JSONP的查询字符串说“添加回调”,或者为window.name添加'what',但我从来没有见过这样的东西。有没有人在野外发现过这个?
替代问题
可能是没有人真正使用这种技术的情况;如果那是真的那么(正如Rob W指出的那样)上面的问题是无法回答的。所以,我的另一个问题是,这种方法有什么问题?这可能有助于解释为什么它没有被真正采用。
我认为,与JSONP相比,这种方法至少有两个好处。
window.name
,恶意站点包含的任何脚本都可以在自己的域中运行。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);
});
我已经设置了一个小提琴来测试here。它使用this script作为测试服务器。
这是一个稍微长一点的例子,可以发出POST请求:http://jsfiddle.net/n9Wnx/2/
摘要
据我所知,window.name
并未作为数据传输流行起来。我想知道我的感知是否准确(因此是原始问题),如果是这样,我想知道为什么会这样。我列举了window.name
似乎对JSONP的一些优势。任何人都可以找出一些可能导致阻止采用这种技术的缺点吗?
更重要的是,任何人都可以给我一个坚实的理由,为什么我不应该使用winow.name
作为数据传输?
window.name
作为交通工具不是特别好,因为(AFAIK)它不会在任何事件发生变化时触发。因此,试图使用window.name
作为双向通信通道的应用程序必须轮询它以进行更新。
至于实际使用它的网站:我从未听说过任何网站。可能有一些,但我只是从纯粹的理论意义上听说过这种技术。
更重要的是,任何人都可以给我一个坚实的理由,为什么我不应该使用winow.name作为数据传输?
虽然window.name
在跨域更改传输数据时可能是一个真正的救星,但它不能用作真正的通用数据传输机制的原因是由于缺少存储和检索数据的API。例如,localStorage
提供setItem
,getItem
。这样的api是抽象实际存储值的方法所必需的,并且可以防止格式冲突(如果你身边运行的不同库以不同的格式存储,就会出现这种情况)。
据我所知,window.name并没有成为数据传输。我想知道我的感知是否准确(因此是原始问题),如果是这样,我想知道为什么会这样。
由于window.name
没有提供这样的存储/检索抽象层 - 如上所述 - 第三方图书馆员无法知道在window.main
中存储数据时使用哪种格式,因此不会使用window.main
,因为它不可靠。如果您(即您的主程序)是唯一一个读取或写入window.name
的人,您可以决定以json格式存储数据并相应地存储/检索。但是,如果第三方库也想要存储/检索某些东西而且它决定不使用json而是选择另一个numerous serialization formats ...这会不小心打破你的json格式并且肯定会造成麻烦。