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 ページにリダイレクト、というかたちも作れる。