window.name作为数据传输:一种有效的方法?

时间:2012-05-12 22:22:36

标签: javascript same-origin-policy

概述和原始问题

window.name是一个有趣的野兽。 MDN的描述暗示了原始意图:

  

窗口名称主要用于设置超链接和表单的目标。 Windows不需要名称。

所以,这意味着我们可以在这个窗口中打开控制台,并写下:

var win = window.open('http://google.com', 'el goog');

...然后让它通过弹出窗口拦截器,它应该在一个名为“el goog”的窗口中打开google.com。由于同源策略,我无法访问name的{​​{1}}属性,但如果我在新窗口中打开控制台并输入win,我将获得{{} 1}}。

如果我将窗口发送回我打开的域(在本例中为stackoverflow.com),我可以获得name属性,但它没有更改。

"el goog"

这意味着我们可以通过设置窗口的name属性来拥有一种跨域会话存储。

如果google.com在窗口被发送回原始域之前更改了win.location.replace(location.href); win.name; // "el goog" ,我们会看到新值而不是“el goog”。这可以用作跨域数据传输,类似于JSONP或CORS的实用程序。

我做了一些搜索,试图找到更多信息,显然是dojo thinks it's legit作为传输。但不知何故,这并不能完全让我放心。所以我的问题是,是否有任何信誉良好的网站使用name作为数据传输?我认为这很容易被发现,因为他们的文档会说“添加'回调'到JSONP的查询字符串,或者为window.name添加'无论什么',”但是我从来没有见过这样的东西。有没有人在野外发现过这个?


替代问题

可能是没有人真正使用这种技术;如果那是真的那么(正如Rob W指出的那样)上面的问题是无法回答的。所以,我的另一个问题是,这种方法有什么问题?这可能有助于解释为什么它没有被真正采用。

正如我所看到的,这种方法比JSONP至少有两个好处。

  • 使用JSONP,您可以信任来自外国的脚本在您的域上运行。使用window.name,恶意网站包含的任何脚本都可以在自己的域中运行。

  • 使用JSONP,无法传递大数据(对于URL来说太大了),也无法进行HTTP POST。使用window.name,我们可以发布任意大小的任意数据。

有什么缺点?


示例实施

以下是客户端实现的一个非常简单的示例。这不处理POST请求,只处理GET。

window.name

我已经设置了一个小提琴来测试here。 它使用this script作为测试服务器。

这是一个稍长的示例,可以发出POST请求:http://jsfiddle.net/n9Wnx/2/


摘要

据我所知,window.name并没有成为数据传输。我想知道我的感知是否准确(因此是原始问题),如果是这样,我想知道为什么就是这种情况。我已经列出了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); });​ 似乎比JSONP更具优势的一些优点。任何人都可以找出一些可能导致阻止采用这种技术的缺点吗?

更重要的是,任何人都可以给我一个坚实的理由,为什么我不应该使用window.name作为数据传输?

2 个答案:

答案 0 :(得分:6)

window.name作为交通运输并不是特别好,因为(AFAIK)它不会在任何事件发生变化时触发。因此,试图将window.name用作双向通信渠道的应用程序必须轮询它以进行更新。

对于实际使用它的网站:我从未听说过任何网站。可能有一些,但我只是从纯粹的理论意义上听说过这种技术。

答案 1 :(得分:0)

  

更重要的是,有人可以给我一个可靠的理由,为什么我不应该将winow.name用作数据传输?

虽然window.name是跨域更改传输数据的真正救星,但之所以无法将其用作真正的通用数据传输机制,是因为缺少用于存储和检索数据的api。例如,localStorage提供了setItemgetItem。这样的api对于从值的实际存储方式中抽象出来并防止格式冲突(如果在您身边运行的不同库将以不同的格式存储会发生)是必要的。

  

据我所知,window.name尚未成为一种数据传输方式。我想知道我的看法是否正确(因此是原始问题),如果这样,我想知道为什么会这样。

由于window.name不提供这样的存储/检索抽象层-如我在上面的观点中所述-第三方库在将数据存储在window.main中时不知道使用哪种格式,因此永远不会使用window.main,因为它不可靠。如果您(即您的主程序)是对window.name的唯一读或写操作,则可以决定以json格式存储数据并相应地存储/检索。但是,如果第三方库也想要存储/检索某些东西并且它决定不使用json而是改用numerous serialization formats的另一个库怎么办...这会意外地破坏json格式并肯定会造成麻烦。 / p>