Web アプリケーションで、JavaScript と Cookie を使っているところは多いと思う。しかし、この 2 つは設定で無効にできるし、そもそも対応してないブラウザもある。そういう場合でもある程度動くようにするのがあるべき姿だが、どうしても必要な場合には、せめて事前にチェックをして、「この Web アプリケーションを使うには JavaScript と Cookie が必要です」みたいなメッセージを出すべきだろう。
では、有効になってるかどうかは、どうすれば判定できるのか。
先日の日記で、browscap.ini ファイルを利用してブラウザの機能や OS バージョンを調べるコンポーネントについて書いたけど、これだけでは「いま設定がどうなっているか」はわからない。
さて、どうするか。
JavaScript 判定
2 種類の方法でリダイレクトを記述し、どちらが使われるかを見る。
<html> <head> <title>設定チェック</title> <script language="JavaScript"> <!-- location.replace("check2.asp?js=1"); //--> </script> <meta http-equiv="Refresh" content="0; URL=check2.asp?js=0"> </head> <body> </body> </html>
この例ではリダイレクト先 URL のパラメータだけ変えているが、もちろんファイルを変えてもよい。……と書いたところで、「クライアントによって動かなかったりしないかな」と不安になったのだが、下記のサイトでほぼ同内容のスクリプトを発見。IE、NN は OK だそうだ。
- JavaScriptのオン/オフ状態に応じて表示するページを変える
- http://www.openspc2.org/reibun/javascript/browser/011/
Refresh が使えないブラウザにも対応する場合は、body 要素内に説明を記述する必要があるだろう。よく見るのは「ページが自動的に切り替わらない場合は、ここをクリックしてください」ってやつ。
(17:33 追記: meta 要素のところ、"URL=" が抜けていたので追加。なお、Refresh も設定で無効にできるようだ。http://altba.com/bakera/hatomaru.aspx/ebi/topic/230 を参照のこと)
ちなみに、ネットで検索すると、
<html> <head> <title>設定チェック</title> <script language="JavaScript"> <!-- function jump() { location.replace("check2.asp?js=1"); } //--> </script> <noscript> <meta http-equiv="Refresh" content="0; check2.asp?js=0"> </noscript> </head> <body onload="jump()"> </body> </html>
という案もあるようだ。ただし、JavaScript に対応しているブラウザの中で、設定で無効にしている場合にも noscript 内を読み飛ばすのがあった気がする (うろ覚え)。また、HTML の仕様に従うと head 要素内に noscript 要素を置くことはできないので、これで動くブラウザがどれだけあるかとか、今後コンテンツ側を XHTML 等に変更しても動くのかとか、無駄な心配を抱え込むことになりそう。
Cookie 判定
実際に発行し、別のページに移動した時に Cookie がついてくるかを見ればいい。その応用で、Cookie でセッションを実現している場合は、セッションで値を保持できるかを見る方法がある。ブラウザに保持できる Cookie のサイズには制限があるので、既に使っている Cookie があれば、使った方がいい。作るのも楽だし。
ASP の場合、最初のページに
Session("CookieCheck") = "1"
とし、別ページにリダイレクトして
Dim gblnCookieEnabled If Session("CookieCheck") = "1" Then gblnCookieEnabled = True Else gblnCookieEnabled = False End If Session.Contents.Remove "CookieCheck"
ってな感じでチェックする。
ちなみに、ASP では、global.asa にイベントハンドラ Session_OnStart を記述できるが、今回の場合、ここで Session("CookieCheck") = "1" をしてもダメ。なぜなら、Cookie を無効にしている場合でも、2 ページ目にアクセスした際に IIS がセッションを作ってしまう。そのため、その後 Session("CookieCheck") を確認すると、"1" が取れてしまう。
組み合わせる
上記の 2 つを組み合わせてみる。JavaScript と Cookie が両方有効になっていれば、index.asp→index2.asp→login.asp という順番でリダイレクトされ、ログイン画面 (login.asp) が表示される、という場合で考えてみる。
まず、index.asp。
<% Session("CookieCheck") = "1" %> <html> <head> <title>index1.asp</title> <script language="JavaScript"> <!-- location.replace("index2.asp?js=1"); //--> </script> <meta http-equiv="refresh" content="0; index2.asp?js=0"> </head> <body> </body> </html>
続いて、index2.asp。
<% gblnJSEnabled = (Request.QueryString("js") = "1") gblnCookieEnabled = (Session("CookieCheck") = "1") gblnReady = gblnJSEnabled And gblnCookieEnabled Session.Contents.Remove "CookieCheck" If gblnReady Then Response.Redirect "login.asp" Else %> <html> <head> <title>index2.asp</title> </head> <body> <ul> <% If Not gblnCookieEnabled Then %><li>Cookie無効</li><% End If If Not gblnJSEnabled Then %><li>JavaScript無効</li><% End If %> </body> </html> <% End If %>
これを変形すれば、正常時の遷移が index.asp→login.asp で、JavaScript か Cookie が使えないときは login.asp から failure.asp ページにリダイレクト、というかたちも作れる。