web-dev-qa-db-ja.com

データ転送としてのwindow.name:有効なアプローチ?

概要と元の質問

window.name は興味深い獣です。 MDNの説明は、当初の意図を示唆しています。

ウィンドウの名前は、主にハイパーリンクとフォームのターゲットを設定するために使用されます。ウィンドウに名前を付ける必要はありません。

つまり、これは、このウィンドウでコンソールを開いて、次のように書くことができることを意味します。

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

...そしてそれをポップアップブロッカーに通すと、「el goog」という名前のウィンドウでgoogle.comが開きます。同一生成元ポリシーのため、namewinプロパティにアクセスできませんが、新しいウィンドウでコンソールを開いてnameと入力すると、 "el goog"を取得します。

開いたドメイン(この場合はstackoverflow.com)にウィンドウを送り返すと、nameプロパティを取得できますが、変更されていません。

win.location.replace(location.href);
win.name; // "el goog"

つまり、ウィンドウのnameプロパティを設定することで、一種のクロスドメインセッションストアを作成できます。

ウィンドウが元のドメインに戻される前にgoogle.comのwindow.nameの値がchangedされていた場合、「el goog。」ではなく新しい値が表示されます。 」これは、JSONPまたはCORSのユーティリティと同様に、クロスドメインのデータ転送として使用できます。

私はより多くの情報を見つけるために少し検索をしました、そしてどうやら道場 それは合法だと思います トランスポートとして。しかし、どういうわけか、それは私を完全に安心させるものではありません。だから私の質問は、window.nameをデータ転送として使用している信頼できるサイトはありますか?彼らのドキュメントは "add 'callback' to the query string for JSONP、or 'whatever' for window.name、」が、私はそのようなものを見たことがありません。誰かが実際にこれを野生で見つけましたか?


別の質問

このテクニックを実際に使用している人はいません。それが本当なら(ロブWが指摘したように)上の質問は答えられません。だから、私の別の質問は、このアプローチの問題は何ですか?これは、なぜ実際に採用されていないのかを説明するのに役立つかもしれません。

私が見ているように、このアプローチにはJSONPよりも少なくとも2つの利点があります。

  • JSONPを使用すると、ドメインで実行する外部のOriginからのスクリプトを信頼できます。 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をデータ転送として使用してはいけないという確かな理由を誰かに教えてもらえますか?

45
Dagg Nabbit

window.nameは、(AFAIK)変更されたときにイベントを発生させないため、トランスポートとして特に適していません。その結果、双方向通信チャネルとしてwindow.nameを使用しようとしたアプリケーションは、更新のためにポーリングする必要があります。

実際にそれを使用しているサイトに関しては、私は聞いたことがありません。いくつかあるかもしれませんが、私は純粋に理論的な意味で議論されたこのテクニックを聞いただけです。

6

さらに言えば、誰かがwinow.nameをデータ転送として使用すべきではないという確かな理由を教えてもらえますか?

_window.name_は、ドメインの変更を越えてデータを転送することに関しては真の救世主になる可能性がありますが、実際のユニバーサルデータ転送メカニズムとして使用できない理由は、データを格納および取得するAPIがないためです。たとえば、localStoragesetItemgetItemを提供します。このようなAPIは、値が実際に格納される方法から抽象化し、フォーマットの競合(ユーザー側で実行されている異なるライブラリが異なるフォーマットで格納する場合に発生する)を防ぐために必要です。

私の知る限り、window.nameはデータ転送としては使用されていません。私の認識は正確であるのか(したがって元の質問です)、そうであるのであれば、なぜこれが当てはまるのでしょうか。

上記のポイントで説明したように、_window.name_はそのようなストア/リトリーブアブストラクションレイヤーを提供しないため、サードパーティのライブラリは_window.main_にデータを格納するときに使用する形式を認識できず、_window.main_信頼できないため。あなた(つまり、メインプログラム)が_window.name_の読み取りまたは書き込みを行う唯一のユーザーである場合は、データをjson形式で格納し、それに応じて格納/取得することができます。しかし、サードパーティのライブラリも何かを格納/取得したいと思っていて、jsonを使用せず、代わりに別の 多数のシリアル化形式 ...を使用した場合、これは誤ってjson形式を壊し間違いなく問題を引き起こします。

1
B12Toaster