ただし、iframeとwindow.nameトランスポートを使用して、Operaでクロスドメインクエリを機能させることができます。 カットの下で、これを行う方法を示し、すべての魔術を実装するシンプルなライブラリを提示します。
一般的に、クロスドメインクエリには次の手法が使用されます。
- プロキシリクエスト。 ページがリモートWebサービスにアクセスするサーバーを所有している場合、サーバーにリクエストをプロキシするスクリプトを実装できます。 したがって、クライアント側では、要求はドメインへの呼び出しのように見えますが、実際には、リモートサーバーでのクエリの結果が返されます。
このアプローチの欠点は、要求元のドメインでサーバーを制御する必要性に加えて、サーバーの着信チャネルの負荷とIPによってプロキシを禁止する機能が含まれます。 さらに、ユーザーデータはサーバーを通過するため、エンドユーザーは私たちを信頼する必要があります。 - フラッシュ経由のリクエスト。 Webサービスを提供するサーバーを所有している場合は、いくつかのドメインからのXDRを許可するXMLポリシーファイルをそのサーバーに配置できます。 短所:Webサービスコントロールが必要、Flashが必要。
-
script
要素の動的生成など、非同期リクエストのさまざまな代替を使用します。 Webサービスの制御が必要です。 さらに、正しいjavascriptを返すには、多少なりとも深刻なコードの変更が必要です。 - クロスオリジンリソースシェアリングの使用 。 繰り返しますが、Webサービスの制御が必要です。さらに、この仕様は、私が知る限り、他のどこでもサポートされていません。
誰かが興味を持っているなら、いつかこれらの古典的なアプローチについて詳しく書きます。 しかし、それらについてはすでに多くのことが書かれています。
一般的なケースでUserJSを記述する場合、スクリプトが起動されるページのサーバーまたはWebサービスへのアクセス権はありません。 したがって、上記の手法を純粋な形で適用することはできません。 しかし、これらの制限を克服する方法があります。
メソッドの本質
すべてが単純なように思えます。リクエストはWebサービスドメインのiframeから行われ、メインページはwindow.nameトランスポートを使用してフレームと通信します。 window.nameプロパティは、一度設定すると、ウィンドウがドメインの境界を越えて移動するときにその値を保持することを思い出してください。
より詳細に。 したがって、
domain.ru
ドメインのWebサービスに非同期要求を行いたい
domain.ru
ドメインの
domain.ru
を作成するとします。 Webサービスへのリクエストは、ドメイン
ws.org
からのドキュメント(たとえば、
ws.org/dummy.gif
/
ws.org/dummy.gif
:重要ではない特定のURL)のiframeで実行されているUserJSによって送信されます。 また、リクエスト引数を渡すには、リモートドメインのページが開く前に、これらのパラメーターを含む行のフレームに
window.name
を設定する必要があります。 したがって、ws.orgのUserJSは、そのwindow.nameから要求引数を受け取り、必要なXMLHttpRequestを
ws.org
ます。 彼にとってはすでに可能です:ws.orgドメイン内のリクエスト。 次に、実行結果はフレームの
window.name
バックされ、フレームは
domain.ru
任意のページ(たとえば
domain.ru/dummy2.gif
)にリダイレクトされ、そこでUserJSが再び実行され、メインウィンドウでクエリ結果ハンドラーが起動されます。
もちろん、正しいキャッシュヘッダーがインストールされている
dummy.gif
および
dummy2.gif
ドキュメントを選択する必要があります。これは、各リクエストがそれらを通過するためです。
図では、次のようになります。
ところで、各ブラウザウィンドウ(およびiframeはウィンドウ)が個別のjavascriptストリームを実行することを覚えておく必要があります。 メインウィンドウスレッドのコンテキストでハンドラーを実行するには、この
window.parent.setTimeout(parent.handler, 0)
コンストラクトのようなものを使用できます。 その点は明らかだと思います。
申込み
last.fmをvkontakte.ruのscrobblerにするために、このメソッドを自作ライブラリの形で実装しました 。
実装はpastebinで確認できます。 58行目では、ペーストビンのバックライトにグリッチがあったため、コメントしました。 もちろん、使用するときにはコメントを外す必要があります。
Requester
オブジェクトがすべての作業を行います。
Requester.request
送信します。 彼は、要求が後で実行されるWebサービスページのアドレスと、自分のドメインのアドレス(例の
dummy.gif
および
dummy2.gif
)を
dummy2.gif
があります。
request
メソッドはiframeを作成し、パラメーターを
dummy.gif
、iframeを
dummy.gif
ます。 コールバックとerrbackをフックできるDeferredオブジェクトを返します(タイムアウト時にerrbackが呼び出されます)。 ws.org/dummy.gifの
ws.org/dummy.gif
は、渡されたパラメーターを
Requester.getArguments()
から取得し、
Requester.getArguments()
を使用してデータを返すことができます。 トークン
Requester
を使用すると、データが自分
Requester
確認します。 つまり、1つのWebサービスに複数のスクリプトが存在する可能性がある場合、トークンを他のWebサービスに変更する価値があります。
Requester
を使用した作業スクリプトはこちらです。