相対パスから絶対パスの作成についての質問です.


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に対して正規表現を使って
相対パスを得る所まではできたのですが
そこから絶対パスの作成するところで詰まってます

回答の条件
  • 1人3回まで
  • 登録:
  • 終了:2008/12/16 21:39:53
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:goodvn No.1

回答回数228ベストアンサー獲得回数18

ポイント50pt

適宜引用元を書き換えてます

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 などを使うべきです

その他の回答2件)

id:goodvn No.1

回答回数228ベストアンサー獲得回数18ここでベストアンサー

ポイント50pt

適宜引用元を書き換えてます

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 などを使うべきです

id:pahoo No.2

回答回数5960ベストアンサー獲得回数633

ポイント20pt

処理的には、パスを後方から参照していき、"./" は無視、"../" で一階層上へ移動すればいいでしょう。


Perl には変換用の関数が用意されています。

File::Spec の rel2abs() です。

id:hujikojp No.3

回答回数101ベストアンサー獲得回数7

ポイント30pt

まず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...

  • id:goodvn
    rel2abs() でも,URL は透過的に扱えないですよね
    たぶん,LWP をまんま使うと,リダイレクトを自動で処理してしまうので,この辺を手動で処理するようにして,本来のパスを手に入れたら,それを rel2abs() に放り込むような使い方になるんでしょうか
  • id:upu
    終了したら,各回答への個別コメントってできなくなりますか……

    >goodvnさん
    リダイレクトが起きていたのですね.なるほど納得しました.
    example.comの事も,勉強になりました.
    ありがとうございます.

    >pahooさん
    今回は,URI->new_abs($filename,$base)を使ってみましたが
    回答ありがとうございます.

    >fujikojpさん
    たしかに,xxx.htmlがディレクトリという可能性もありますね(ひどいディレクトリ名ですTT
    最後が/で終わるURLは,サーバー側が,
    index.htmlやindex.phpもしくは,そのディレクトリにあるファイルリストを出力したりしますが
    それをするのがサーバー側であって,ブラウザ側じゃないというのが私の認識です
    うまく伝わらなかったようですね・・・
    細かいことをありがとうございました.

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません