WEB相談室

Webページ作成に関しての何でも掲示板です。

タイトル:PHPのLocation headerで

0:[投稿] ひよこ [2002/03/26 00:00 ][環境:WIN+IE UNIX系+OTHER]

今回は質問です。
Apache+PHP4

index.phpをアクセスした場合に自動で携帯端末やPCへ振り分けるスクリプトをPerlから移植しているのですが、PHPのheader()が思うとおりの動作をしてくれません。
スクリプト:(1行目はCGIとして動作させるために必要)
#!/usr/local/bin/php
<?php
## 表示するファイルの名前
$file_i = "i.html";    # i-Mode
$file_j = "j.html";    # J-PHONE
$file_a = "astel.html";    # ドットi
$file_e = "index.hdml";    # EzWeb
$file_h = "index.txt";    # H"
$file_p = "index.html";    # 上記以外(PC)

$content = "text/html";

if (preg_match("/DoCoMo/i",$HTTP_USER_AGENT)){
    $file = $file_i; $type = "1";
}
elseif (preg_match("/J-PHONE/i",$HTTP_USER_AGENT)){
    $file = $file_j; $type = "2";
}
elseif (preg_match("/ASTEL/i",$HTTP_USER_AGENT)) {
    $file = $file_a;  $type = "3";
}
elseif (preg_match("/UP\.Browser/i",$HTTP_USER_AGENT)) {
    $file = $file_e;  $type = "4";
    $content = "text/x-hdml;charset=Shift_JIS";
}
elseif (preg_match("/PDXGW/i",$HTTP_USER_AGENT)) {
    $file = $file_h;  $type = "5";
    $content = "text/plain";
}
else { $type = "0"; $file = $file_p; }

//header("Content-type: $content");
if ($file) {
    header("Location: $file");
    exit;
}
else {
    if ($type <= 3) { print ("<html>\n<head><title>Error</title></head>\n<body>\n"); }
    elseif($type == 4) { print ("<hdml version=3.0>\n<DISPLAY>\n"); }
    if ($type != 5) { print ("<center>エラー<br><br>"); }
    if ($type <= 3) { print ("</center>"); }
    if ($type == 5) {
        print ("X-PmailDX-CTRL: LineDisconnect\n");
        print ("Sbject: エラー\n");
        print ("Content-Type: Text/Plain\n\n");
    }
    print ("ご使用のブラウザでは閲覧できません。\n");
    if ($type <= 3) { print ("</body>\n</html>\n"); }
    elseif($type == 4) { print ("</display>\n</hdml>"); }
exit;
}
?>

.htaccessの内容
DirectoryIndex index.php index.html index.htm index.shtml


質問:1
http://www.hogehonya.com/index.phpでアクセスすると希望通りに動作する。
PCだとindex.htmlへJ-PHONEだとj.htmlへ
しかし、http://www.hogehonya.com/ でアクセスすると "302 Found The document has moved here."
(here部分が正規の飛び先URLへのアンカーになっている)
となってしまう。どうしたら自動で飛べるようになるのか。
.htaccessがおかしい?

質問:2
コメントアウトしている、header("Content-type: $content");は必要なのか?(必要かどうかを確認するためコメントアウトしてみた)
PC及びJ-PHONEでは無くても大丈夫の様ですが、EzWebやHではどうなのか?
尚、この部分は質問1の動作に関係ありませんでした。

以上宜しくお願いします。


1:[質問] ひよこ [2002/03/26 00:06 ]

追記:
Location: $file\n\n でも同じで、変化はありません。


2:[回答] 通りすがりX [2002/03/26 01:47 ]

質問1
APACHEの正規の動作だったような・・・
SSI(PHP)でクライアントに応じた内容を出力してはどうでしょう?
i-Modeだけですが、ウチでの携帯端末への対処はそうやってます。

質問2
i-Modeでも古いものはリダイレクトに対応していない機種が
有りましたが、もしかすると・・・


3:[質問] ひよこ [2002/03/26 02:43 ]

> APACHEの正規の動作だったような・・・
・・ですかぁ(;_;)。申し忘れましたが、ローカルでの動作ではちゃんとhtmlへ飛んでくれるんです。質問の動作は実際にWebサーバへUPした状態なのですが、なにせローカルでは携帯からアクセスできないので実サーバーでテストしてました。

> SSI(PHP)でクライアントに応じた内容を出力してはどうでしょう?

逆の方法として各HTMLをAgentに応じてincludeする事も考えてはいますが、出来るだけ今の方法でできればと、考えてます。
ダメなら仕方ないですけど。

質問2の方ですが、Webで探してみるとPHPからはこのContent-typeを出力するサンプルは見かけません。
検証も簡単に出来ないので辛いです。

そこで、Content-typeを出力なしでサンプルを上げてみました。
J-PHONE及びPC以外でアクセス出来る方リポートをいただけたら幸いです。
http://hiyoko.s9.xrea.com/
(注:表示広告の「出会いステーション」は本件と関係ありません)


4:[回答] 通りすがりX [2002/03/26 11:10 ]

>APACHEの正規の動作だったような・・・
すみません勘違いでした。
/dir と呼び出した時のネゴシエーションと勘違いしてました。

件のURLを見るとCGI認証を行いたいようですね。
考えられる問題として、
1、このサーバーでは自動挿入される広告画像のサイズだけでも10Kb程度有るので携帯には向かないのでは?
2、前記したように前に同じ様なCGIを作った時、Location: 〜に対応していない端末が存在した。
  その対応として、端末を見分けてリンク付きのページを出力しました。

インクルードするタイプ(サーバー側で処理)の方が、端末の動作に依存しないので簡単ですよ。
また各端末のページデータも、pc.html、i.html、j.html〜と用意しておきファイルを読み込んで
出力するだけの簡単なもので大丈夫だし、文字列置き換えも自由にできるのでお勧めです。

セッションクッキーかページソースにセッションIDを埋め込めば認証を持ちまわれるし、
i-Modeのatn(のようなもの)を使えば携帯でも簡単に認証が可能です。

いずれにしても Location: 〜 の振り分けは以前使おうとして諦めた覚えがあります。


5:[回答] たこすけ [2002/03/26 12:44 ]

> 質問:1
1. header("Location: http://www.hogehonya.com/$file"); とする。
2. DirectoryIndex index.php のみとする
3. PC用のファイル名を index.html 以外にする

どれかを試してみて下さい。


6:[回答] ひよこ [2002/03/26 13:08 ]

>>4
通りすがりXさん、ありがとうございます。
先のテストアップのサイトは本当にテストだけです。
広告は携帯専用ですのでPCの時とは違います。
でもインクルードするやり方が良さそうですね。検討します。

>>5
たこすけさん、ありがとうございます。
> 1. header("Location: http://www.hogehonya.com/$file"); とする。
この記述は試していないですが、URLをhttp〜に変更した物は試しました。
> 3. PC用のファイル名を index.html 以外にする
これも試しました。
> 2. DirectoryIndex index.php のみとする
これは試していないのでちょと実験してみます。

また、質問2の方や携帯での状況など何かありましたら引き続き宜しくです。



7:[回答] TOM neko [2002/03/27 01:57 ]

質問1
広告が割り込んでくるので飛ばなくなるようですね。サーバの仕様でしょう。
質問2
Location:で飛ばすなら、その前にContent-type指定は要らないです。必要なら飛び先のページの方で指定することになりますね。
ついでに、仕様ではLocation:には絶対URLで指定です。


8:[完了] ひよこ [2002/03/27 11:42 ]

>>7
TOM nekoさん、ありがとうございます。
広告ですね、言われてみてわかりました。
どおりでローカルでは旨くいくわけです。
広告を挿入させない方法は公開されていますが、Locationヘッダーではどうしようもなさそうです。
あ、そうか!Location headerの前に余分な出力を伴っていたわけですね。理解できました。
本番はもちろん広告など無いのでとりあえず解決です。
Locationの絶対URLも理解いたしました。
他の携帯端末はいずれ調査しますが、今回は完了です。ありがとうございました。


9:[関連] えび [2002/03/27 12:05 ]

>>7
>Location:で飛ばすなら、その前にContent-type指定は要らないです。必要なら飛び先のページの方で指定することになりますね。
 リダイレクト応答にも Content-Type は必要です。スクリプト側で Content-Type を吐かなくても動作しますが、それは「Apache などが補完してつけてくれているから」です。「飛び先にあれば良いからつけなくて良い」というわけではありません。

 ちなみに、Location: フィールドを受け取った UA は必ず遷移する、と考えるのもちょっと甘いです。たとえば、Netscape 4.x 系に対して 303 See Other で応答すると、Location フィールドの内容は無視されて「ページを表示」しようとします。

 まあ役には立たないでしょうが参考まで。


10:[完了] ひよこ [2002/03/27 14:00 ]

結果報告です。
結局、FAQなどをあさっていたらサーバー仕様と言うことがわかりました。
対処として、
1.ファイル名無しアクセス
2.index.htmlが呼ばれる。metaのrefreshでindex.phpを呼ぶ
3.index.phpで振り分け、locationヘッダーで飛ばす。

とちょっとややこしいことをやってみましたが旨く動作しました。
XREAは.htaccessへのDirectoryIndexは禁止だそうで、このようになりました。
以上ご報告です。

回答(必須): 状態:

お名前(必須):

e-mail:

URL:




[戻る]

ChaichanPAPA's World