3xx リダイレクトを追跡してダウンロードする方法
3xx リダイレクト
HTTP プロトコルでは、ファイルの場所が変わったとき、すなわち、同じものに対する URL が変わったときに、 クライアントに対して、それを知らせる方法があります。
それが 3xx リダイレクトです。
例えば、ファイルの場所が変わったときは、サーバーは "301 Moved Permanently" というステータスをクライアントに返します。
このステータスによって、クライアントは「今度からは新しい URL をリクエストしないといけない」ということを知るのです。
では、新しい URL はどこになるかというと、それを示すのが Location ヘッダ です。
サーバーは 301 ステータスを返すときに、Location を含めて応答します。
例えば、次のようになります。
GET /foo.jpg HTTP/1.1 Host: example1.jp Accept: */*
このように、foo.jpg を要求したところ、そのディレクトリが変わっているとすると、 サーバーは次のようなステータスを返して、クライアントに対してその URL が変わったことを示します。
HTTP/1.1 301 Moved Permanently Server: Apache Location: http://example1.jp/images/foo.jpg Content-Length: 240 Connection: keep-alive ...
クライアントは、この Location ヘッダで示される URL に対して再度要求を行えばよいのです。
尚、301 は Permanently(永久的な) 移動の場合に利用し、302 や 307 は一時的な移動 (Temporary Moved/Redirect) を示します。 また、303 (See Other) というステータスもあります。
いずれにせよ、新しい URL は Location ヘッダを見ることでわかります。
URL が変わってしまうと、元のページがアクセスを集めていた場合、 それがアクセスされなくなってしまうのは大変もったいない話です。
URL が変わる場合には 301 リダイレクトを利用して、検索エンジンなどにもその変更を教えるようにしましょう。
一時的な変更の場合は、とりあえず 302 でクライアントにその変更を教えるとよいでしょう。
Location ヘッダを追跡して移動先のファイルをダウンロードする方法
少々前フリが長くなってしまいましたが、そういう事情で、ある URL を要求した後、 そのファイルが移動してしまっており、Location ヘッダをみて、再度新しい URL へ要求を出したい場合があります。
PHP (cUrl) では、ロケーションヘッダを見るためのオプション CURLOPT_FOLLOWLOCATION があります。
これを用いることで、透過的に新しい URL からのファイルを取得することができます。
コードは次の通りです。
$ch = curl_init ($img_url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_BINARYTRANSFER,1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_MAXREDIRS, 3); $rawdata=curl_exec($ch); curl_close ($ch);
尚、リダイレクトを追跡することになるので、リダイレクト回数の上限設定 CURLOPT_MAXREDIRS も行う必要があります。