« 妻に捧げる「Intel Mac (Mac mini)を買いたい5つの理由」 | トップページ | Mac版IE5.23(Panther、Tiger)とチルダの文字化け »

2006/09/04

Mac版IEのRefererバグ



【VISA/MasterCard】ネットで簡単申込!最短10分自動審査/スピード発行!

既に配布が中止になっているMac版IEには、さまざまなバグが存在します。そして、このバグは今後修復される可能性はありません。しかし、一方で、現在も1%強のユーザーがMac版IEを使っていることを考えるならば、完全に無視することもできません。さまざまなバグの中で今日は一つ紹介したいと思うのが、Refererのバグです。

フレームページの場合、子フレームのRefererとして親フレームのURLが残るのが普通です。しかし、現在、利用されている、0.2%以上のシェアを持つブラウザの中で唯一、Mac版IEでは、子フレームのRefererは空となります。直接、子フレームにアクセスされているのか、想定している親フレームの中で表示されているのか、はたまた想定外のページの子フレームにされてしまっているかは、Mac版IEの場合、Refererのチェックでは分かりません。

Refererのテスト(サンプル):
http://www.shtml.jp/blog/macie_frame.html

上の例では、Mac版IE以外の主要なブラウザでは、子フレームのRefererは親フレームである「http://www.shtml.jp/blog/macie_frame.html」となります。

このバグは、マイクロソフト社も公式技術文書の中で認めています。

●フレームを使用したページで Referer ヘッダーが送信されない
http://support.microsoft.com/kb/822361/ja?spid=2071&sid=global

そのため、親フレームが特定のURLであることをチェックするためには、Mac版IEでは、Refererのチェックという手法は不可ということになります。

(そもそも、Refererは善意のアクセス者をはじく可能性が常にあります。Norton Internet Secuirtyなどの製品を使っている一般ユーザーの端末では、ユーザーが意識することなく、Refererの送出が遮断されていることがあるためです。

●参照元 (リファラ) が遮断され、Web サイトが正しく表示されない (Norton Internet Security 2003/Norton Personal Firewall 2003)
http://service1.symantec.com/SUPPORT/INTER/nisjapanesekb.
nsf/jp_docid/20021020160209947


単に、子フレームに直接アクセスされたくないということであれば、JavaScriptで、

とするだけで十分でしょう。

しかしながら、上のJavaScriptですと、他のサイトが自分のホームページをフレーム内に入れてしまった場合には、window.topとwindow.selfは異なるため、location.replaceで「想定している親フレーム」にリダイレクトされることはありません。そのため、そのような危険性の対策としては不十分なことになります。

そこで、上のJavaScriptを少し改良するなら、
とすれば、とりあえずは良さそうです。

ここで、「try catch」で例外処理をしているのがポイントとなります。これをしないで、

としても、「書き込みできません」(Windows版IEの場合)、「エラー: uncaught exception: Permission denied to get property Location.href」(Windows版Firefoxの場合)、「ReferenceError(Security error: attempted to read protected variable)」「Unsafe JavaScript attempt to access frame with URL (親フレームのURL)from frame with URL (子フレームのURL). Domain must match」(Safariの場合)というエラーが出てうまくいきません。このように、If節の部分でエラーが出ますので、location.replaceで想定している親フレームのURLにリダイレクトさせることが不可となります。そこで、例外をキャッチするために「try catch」を使っています。

なぜ、if節でエラーが出てしまうかと言えば、すでに英語のエラーメッセージにも表れていますように、ドメインの異なるlocation.href(URL)を参照しているためです。セキュリティ上の理由のため、値を取得できません。ですから、「try catch」を使います。しかしながら、例2のように「try catch」を使っても、うまく動作しないブラウザがあります。



まずは、今は絶滅寸前のNetscape 4.xです。「try catch」そのものをサポートしていないため、エラーになります。解決策はありますが、これは単純に「無視」でいいかもしれません。ただ、実は、例2の書き方では、他ならぬMac版IEでエラーが発生します。例外をキャッチした場合の処理=「window.parent.location.replace("想定される親フレームのURL");」の部分です。ここの部分もさらに「try catch」の入れ子にすればよさそうですが、結局それでは、他人の親フレームの中に自分のコンテンツが表示されている状況自体は変わりません。

そうは言っても、仕方がないので、Mac版IEでは、親フレームのURLを強制変更させるのはあきらめて、あくまでも子フレーム内の表示をエラーメッセージや空白ページを表示させることで自爆・自害させる(=勝手に人のホームページを自分のホームページに入れてしまってくれている輩にダメージを与える)手を考えてみます。他人のホームページのコンテンツにされるぐらいなら自爆の道を選ぶということになります。

これなら、Mac版IEでも動作します。しかし、実は、Safariでも、問題が発生するため、例2及び例4の使い方は結局は中途半端になります。「try catch」自体はSafariでもサポートされていますが、この例ではなぜか、うまく動作しません。例外がスクリプト内でcatchされることなく、そのままコンソールにエラーログがたまります。

これだと、Mac版IEのバグをフォローしようとして、結局、より大きなシェアのSafariで問題が発生することとなり、意味がないことになりかねません。では、折衷案にして、

とすればいいかもしれません。

ですが、正直な話、ここまでするのも面倒ですね。どこまでするかは考え方次第でしょうが・・・。

 上のサンプルはあくまでも、「もともとフレーム内に表示されるべきページだけれど、他のホームページのフレーム内には表示されたくない」という場合にどうすればいいかという例であり、元々フレームでないページあれば、逆に「フレーム内に表示されていたらエラー」とすればいいことになり、この場合はもう少し簡単なプログラムで大丈夫なはずです。フレーム内に表示されている場合は、Mac版IEとSafari以外のブラウザでは、「window.top.location.replace("そのURL");」としてフレームを強制解除し、Mac版IEとSafariの場合は、(ドメインが異なる場合、アクセスエラーとなるため、)親フレームの変更は諦めて、「location.replace("自爆用のURL");」とすればいいことになりそうです。



|

« 妻に捧げる「Intel Mac (Mac mini)を買いたい5つの理由」 | トップページ | Mac版IE5.23(Panther、Tiger)とチルダの文字化け »

コメント

コメントを書く



(ウェブ上には掲載しません)


コメントは記事投稿者が公開するまで表示されません。



トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/67411/11756482

この記事へのトラックバック一覧です: Mac版IEのRefererバグ:

« 妻に捧げる「Intel Mac (Mac mini)を買いたい5つの理由」 | トップページ | Mac版IE5.23(Panther、Tiger)とチルダの文字化け »