2008-03-14(金) [長年日記]
■ 「Amazon 退会」でググると一位な件
どうもアクセスが多いと思ったら、「Amazon 退会」でググると2003年11月11日の日記が一位だった。退会方法なんて、ツッコミに「メールで」ってあるだけでほとんど何も書いてないのに……。つーか、こないだのmixi規約改定の件といい、どいつもこいつも即座に反応しすぎ。
ちなみに、退会しても購入履歴は残るそうなので、無駄なあがきらしいですよ。
■ 存在しない静的ページへアクセスがあったらその場で生成したいんだが
煮え切らない試行錯誤のメモ。
たとえば、現時点では存在しないページ:
http://example.com/hoge.html
にアクセスがあったとする。でもhoge.htmlは存在しないので、404になる。そこでErrorDocumentディレクティブを使って、CGIのページに飛ばす:
ErrorDocument 404 /cgi-bin/generate.cgi
generate.cgiの中ではファイルhoge.htmlを生成して……さてここからが問題。
素直にLocationヘッダで生成後のhoge.htmlに飛ばしてもうまくいかない:
puts "Location: hoge.html\n\n"
IE7は空っぽの表示になった。ループを検知したのか、キャッシュが悪さをしているのか。そもそも404のままじゃまずいだろ。
じゃあ、generate.cgiのレスポンスをHTMLにして、meta refreshで飛ばしてはどうか:
puts <<-RES Content-Type: text/html <html><head> <meta http-equiv="refresh" content="1;url=hoge.html"> </head></html> RES
これはうまくいく。でも検索エンジンボットはたどってくれないから、不都合が多い。同様な理由でJavaScriptも採用したくない。
あ、Locationヘッダだけ指定するとステータスが404のままだからダメなのか? 303にしたら、なんかうまくいったんだけど、偶然だろうか*1:
puts <<-RES Status: 303 Moved Permanently Location: hoge.html RES
最終的にブラウザに返るステータスも200なので、これでいいなら楽だなぁ。RFCだけだとよくわからん。ぜったい誰かがやってるはずなので、ベストプラクティスがあるに違いないのだが。
続く。
*1 wgetはなぜか303でエラーだと言ってるが。IE7、Firefox、w3mはちゃんと移動してくれる。
mod_rewriteは使わないという前提ですか?
そうですね、mod_rewriteは最後の武器ってとこで。
ああ、rewriteなしですか。。。
$ cat .htaccess
RewriteEngine On
# if no cache file, run cache.cgi
RewriteCond %{REQUEST_FILENAME} !-s
RewriteRule ^(.+)$ ../cache.cgi?$1 [T=application/x-httpd-cgi,L]
あ、問題は、ここの部分でしたね。
>素直にLocationヘッダで生成後のhoge.htmlに飛ばしてもうまくいかない:
生成までは行ってるんですね。
うちでは、htmlファイルを生成したあと、そのhtmlファイルの内容をContent-typeのヘッダの後に送り出してます。
>setu
CGIの出力をそのまま返せるのは、mod_rewriteのおかげで404を返していないからですね。やっぱmod_rewriteを使うのが一番素直なのかなぁ。
Apacheにできるだけ依存しない方法にしたいんですよね……。
そうですか。cgiが走る前に404を返されちゃうんですか。上のやりかたを作るときにエラーページの呼出しからキャッシュhtmlを生成している例も見た覚えがありますので、出来るはずだと思いますが、ずいぶん前の事なので。。。。
単純にgenerate.cgiでファイルを生成後、Status: 200+作ったファイルの中身を返す、という手はいかがでしょうか?
ErrorDocument方式でもいけるようですが…
えっ、そんな単純な話!? >hs
たしかにちゃんと動きますねぇ……以前tDiaryでErrorDocumentを使ったときは404になっちゃって困った記憶があるんだけど。勘違いだったか。