http://xxx.xx/xx/(ファイル名省略,サーバー側で補完
http://xxx.xx/xx (xxの最後の/を省略,サーバー側が補完
http://xxx.xx/xx/xx.html (xx.htmlを返す
http://xxx.xx/xx/y.yy (y.yyがディレクトリかファイルかをサーバー側が判断して適切なファイルを返す
URLの書き方には上記の様に種類がありますが
(この認識であってますよね?)
そのファイル内で,相対パスでのリンク(<img src="images/z.jpg">)を見つけたとき
ブラウザ等はどうやって絶対パスを作成しているのでしょうか?
URL記述の省略形も多いので,最後に現れる/以降を削って,相対パスをつなげるだけではできませんよね?
【やりたいこと】
perlで
検索サイトから得た,画像の載っているページのurl(省略されているかもしれない)
と画像ファイル名(z.jpg)を得て
それを元に,画像の絶対パスの作成
my $ua = LWP::UserAgent->new;
my $res = $ua->get($url,'User-Agent' => '(略)');
my $html = $res->content;
をして,HTMLに対して正規表現を使って
相対パスを得る所まではできたのですが
そこから絶対パスの作成するところで詰まってます
適宜引用元を書き換えてます
http://example.com/xx/(ファイル名省略,サーバー側で補完
正確に言うと,補完ではなくて,"/xx/" というパスに対し,コンテンツを返答します.このコンテンツの絶対パスは,"/xx/" になります
http://example.com/xx (xxの最後の/を省略,サーバー側が補完
サーバ側の設定によりますが,DirectorySlash が設定されている場合,"/xx" がディレクトリにマッチングする場合,"/xx/" に対するリダイレクトを返します
ブラウザはこれを受けて,"/xx/" へ再度アクセスします
ブラウザから見た場合,文字列だけでは,"/xx/y.yy" がディレクトリかファイルかはわかりませんが,実際にアクセスする時点で,判明します
もし,サーバが,"/xx/y.yy" というリクエストに対し,リダイレクトではなく,直接コンテンツを返した着た場合,このコンテンツ中に含まれる,"images/z.jpg" という相対リンクは,"/xx/images/z.jpg" を指していると認識します
つまりは,文字列だけでは,正確なパスはわかりませんので,実際のアクセスが必要です
あと,こうした URL の例題を取り扱う場合,予約された独自ドメイン名,example.com などを使うべきです
適宜引用元を書き換えてます
http://example.com/xx/(ファイル名省略,サーバー側で補完
正確に言うと,補完ではなくて,"/xx/" というパスに対し,コンテンツを返答します.このコンテンツの絶対パスは,"/xx/" になります
http://example.com/xx (xxの最後の/を省略,サーバー側が補完
サーバ側の設定によりますが,DirectorySlash が設定されている場合,"/xx" がディレクトリにマッチングする場合,"/xx/" に対するリダイレクトを返します
ブラウザはこれを受けて,"/xx/" へ再度アクセスします
ブラウザから見た場合,文字列だけでは,"/xx/y.yy" がディレクトリかファイルかはわかりませんが,実際にアクセスする時点で,判明します
もし,サーバが,"/xx/y.yy" というリクエストに対し,リダイレクトではなく,直接コンテンツを返した着た場合,このコンテンツ中に含まれる,"images/z.jpg" という相対リンクは,"/xx/images/z.jpg" を指していると認識します
つまりは,文字列だけでは,正確なパスはわかりませんので,実際のアクセスが必要です
あと,こうした URL の例題を取り扱う場合,予約された独自ドメイン名,example.com などを使うべきです
処理的には、パスを後方から参照していき、"./" は無視、"../" で一階層上へ移動すればいいでしょう。
Perl には変換用の関数が用意されています。
File::Spec の rel2abs() です。
まずURLに関する認識が間違っています。
1. http://example.com/xxx/ は、ディレクトリ(正確にはHTTP URLにはディレクトリという概念はありませんが) をあらわすもので、サーバが補完することは期待されてません(もちろん、そういうサーバもありえますが)。例えば、ディレクトリの内容自体を返したりすることもあります。
2. のこりの3つは、URLの構成的には同じものです。URLには拡張子という概念はありません。 http://example.com/xxx/xxx.html が実はディレクトリで http://example.com/xxx/xxx.html/ にredirectされることもありえます。
まあ、redirectは LWPがやってくれるそうなので、それほど気にしなくてもいいのかもしれません。
で、原則的には、Base URLの「最後に現れる/以降を削って,相対パスをつなげるだけ」でokなはずです。
あと、最近は用いられることはないのかもしれませんが、base要素あたりも気にしておくべきでしょう。
以下も参考まで:
http://www.w3.org/TR/html401/struct/links.html#resolving-relativ...
コメント(2件)
たぶん,LWP をまんま使うと,リダイレクトを自動で処理してしまうので,この辺を手動で処理するようにして,本来のパスを手に入れたら,それを rel2abs() に放り込むような使い方になるんでしょうか
>goodvnさん
リダイレクトが起きていたのですね.なるほど納得しました.
example.comの事も,勉強になりました.
ありがとうございます.
>pahooさん
今回は,URI->new_abs($filename,$base)を使ってみましたが
回答ありがとうございます.
>fujikojpさん
たしかに,xxx.htmlがディレクトリという可能性もありますね(ひどいディレクトリ名ですTT
最後が/で終わるURLは,サーバー側が,
index.htmlやindex.phpもしくは,そのディレクトリにあるファイルリストを出力したりしますが
それをするのがサーバー側であって,ブラウザ側じゃないというのが私の認識です
うまく伝わらなかったようですね・・・
細かいことをありがとうございました.