そこで、VKontakteのiframeアプリケーションを開発するときに考えました。
しかし、アプリケーションが開発された後(開発は主にMozilla FirefoxとGoogle Chromeで行われました)、Internet Explorerでは機能しなくなり、後にOperaとSafariの最新バージョンが加わりました。
カットの下で、問題とその解決策の詳細な説明。
問題の説明
まず、 Cookieがサーバーによって正常に送信され、ブラウザーによって受け入れられることが確立されましたが、その結果、 Cookieは保存されず、次の要求と共にサーバーに戻されません。
動作は奇妙に見えましたが、客観的な正当性があります。ブラウザはページを表示するためのプライバシーを提供し、 iframe内のページからのCookieを受け入れません。
例を挙げましょう。
ラップトップを手に取り、ベンチマークとさまざまなラップトップの比較を使用してWebページを読むとします。 これらのページの一部には、Google AdSenseまたは他の同様のシステムがインストールされます。これにより、 Cookieを介して一意の値を送信し、それによってさらにユーザーを識別することができます。 後で、お気に入りのフレームワークに関するニュース、ドキュメントを読んだり、フォーラムでのディスカッションに参加したりすると、広告でラップトップを購入するための広告が表示されることに驚くでしょう。 それまでの間、広告配置システムは誰かのクリック率を増加させます。 ;)
ブラウザはこの種の情報収集から私たちを保護し、 iframe内のページからのCookieの受け入れを禁止しようとします。
しかし、私たちは広告や情報の収集とは一切関係がないため、問題を解決するためのオプションを検討します。
iframeおよびInternet ExplorerのCookie
私たちの場合、Internet Explorerの解決策はすぐに現れました。問題は何度も調査され、答えはGoogleですぐに見つかりました。
解決策は、次のコンテンツを含むHTTPヘッダーを送信することです。
P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"
特に、PHPの場合は次のようになります。
<?php header('P3P: CP="IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT"');
iframeおよびOpera / SafariのCookie
これらのブラウザの問題はそれほど昔には現れなかったため、それを特定して解決することはもう少し困難でした。
問題の本質は、これらのブラウザーの最新バージョンでは、デフォルトのチェックボックスが「Cookie:訪問したサイトからのみ受け入れる」 (Opera)および「Cookieを受け入れる:訪問したサイトからのみ」 (Safari)であることです。
この問題の明らかな解決策は、Cookieを受け入れるモードを「常に」に変更することです。 ただし、ほとんどの場合、すべてのユーザーにこれを「依頼」することはできません。
したがって、問題を解決する他の方法を検討してみます。
方法1.最初のページの代わりにスプラッシュスクリーン
問題のより詳細な調査により、ユーザーのアクションの前にCookieが設定されないことが示されました。 ユーザーがリンクをクリックしてiframeの別のページに移動すると、 Cookieが正常に受け入れられ始めます。
別のページへの移行をエミュレートしても効果がないことに注意してください。 すなわち:
- HTTPロケーションヘッダーを使用したリダイレクト
- 適切なメタタグを使用してリダイレクトする
- window.locationをJavaSctiptから変更してリダイレクトする
- JavaScriptからリンクのclick()メソッドを使用してリダイレクトする
明らかな解決策:実際のサイトの代わりに、最初のページに「go to the application」というリンクが付いたユーザーへの挨拶が表示されます。
利点:
+シンプル、防弾
+ブラウザで有効になっているJavaScriptの独立性
短所:
-ユーザーによる追加のアクションが必要
-堅牢性(「わかりにくい」挨拶のある追加ページ)
方法2.フォーム送信を使用したリダイレクト
ある理由でリストした遷移の遷移をエミュレートする方法では、フォームを送信することによるリダイレクトはありません。
メソッドの本質:
- iframeがフォームに作成され、そのアクションが現在のドメインの目的のページにつながる
- JavaScriptを介して送信されたフォーム
また、この方法は機能します。フォームのアクションアドレスにあるスクリプト(およびその後に呼び出されるスクリプト)がcookieを正常に設定します。
フォームがGETメソッドまたはPOSTメソッドを使用して送信されたかどうかは関係ありません。
jQueryを使用した実装例:
<script type="text/javascript"> $(function(){ $('body').append('<form id="cookiesHackForm" action="http://example.com/" method="get"></form>'); $('#cookiesHackForm').submit(); }); </script>
利点:
+ユーザーのアクションは不要
短所:
-JavaScriptが必要
-リダイレクト専用の空白ページが必要
方法3.追加のiframeを使用してバックグラウンドでフォームを送信する
これは、リダイレクトの欠如をなくす2番目の方法の開発です。
リダイレクト用の余分な空白ページを避けるために、上記のフォームを送信する追加のiframeを作成できます。 したがって、ユーザーに便利なページを表示し、 Cookieを 「バックグラウンドで」設定します。
jQueryを使用した実装例:
<script type="text/javascript"> $(function(){ $('body').append('<iframe id="cookiesHackFrame" name="cookiesHackFrame" src="http://example.com/blank.html" style="display:none;"></iframe>'); $('body').append('<form id="cookiesHackForm" action="http://example.com/" method="post" target="cookiesHackFrame" >'); $('#cookiesHackForm').submit(); }); </script>
利点:
+ユーザーのアクションは不要
+リダイレクトは不要
短所:
-JavaScriptが必要
-Cookieを設定した後にのみページの出力が発生する場所は意味がありません
おわりに
ブラウザは私たちのプライバシーを気にしますが、回避策があるため、これらのパスがバグなのか機能なのか疑問に思います。 最初のケースでは、対応するパッチのしばらく後に、そのような方法で問題を解決することを拒否する必要があります。 しかし、彼らが働いている間、それらの使用を拒否する理由はありません。
関連リンク
http://www.w3.org/TR/P3P/#guiding_principles
http://stackoverflow.com/questions/389456/cookie-blocked-not-saved-in-iframe-in-internet-explorer
http://stackoverflow.com/questions/2691864/facebook-iframe-app-with-multiple-pages-in-safari-session-variables-not-persistin
http://developers.facebook.com/docs/best-practices#miscellaneous-issues
http://anantgarg.com/2010/02/18/cross-domain-cookies-in-safari/
http://lightyearsoftware.com/2009/11/on-the-pain-of-developing-for-facebook/
http://javascript.ru/unsorted/id(thx seriyPS )
UPD:誰かがより適切なブログを提案した場合、私は非常に感謝します。
UPD2:推奨事項についてブログブラウザーに移動しました。 (thx agul )