25

URLのヘッドリクエストを実行し、応答ヘッダーを出力する単純なコードがあります。一部のサイトでは、これが完了するまでに長い時間がかかる場合があることに気づきました。

たとえば、リクエストhttp://www.arstechnica.comには約2分かかります。同じ基本的なタスクを実行する別のWebサイトを使用して同じリクエストを試しましたが、すぐに返されます。ですから、私が間違って設定したものがこの遅延の原因になっているに違いありません。

これが私が持っているコードです:

$ch = curl_init();
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt ($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

// Only calling the head
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'

$content = curl_exec ($ch);
curl_close ($ch);

同じ機能を実行するWebサイトへのリンクは次のとおりです。http ://www.seoconsultants.com/tools/headers.asp

上記のコードは、少なくとも私のサーバーでは、www.arstechnica.comを取得するのに2分かかりますが、上記のリンクのサービスはすぐにそれを返します。

私は何が欠けていますか?

4

5 に答える 5

48

少し単純化してみてください。

print htmlentities(file_get_contents("http://www.arstechnica.com"));

上記は私のウェブサーバーに即座に出力されます。それがあなたのものでない場合、あなたのウェブホストがこれらの種類のリクエストを抑制するために何らかの設定をしている可能性が高いです。

編集

上記はすぐに発生するため、元のコードに次のカール設定を設定してみてください。

curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);

http://www.arstechnica.comあなたが投稿したツールを使用して、送信されたリクエストに対して301ヘッダーが送信されていることに気付きました。cURLがこれを取得していて、指定された新しい場所に従わないため、スクリプトがハングする可能性があります。

2番目の編集

不思議なことに、上記と同じコードを試してみると、私のWebサーバーもハングしていました。私はこのコードを置き換えました:

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'

これとともに:

curl_setopt($ch, CURLOPT_NOBODY, true);

これは、マニュアルがHEADリクエストを実行することを推奨する方法です。それはそれを即座に機能させました。

于 2009-04-20T21:35:48.307 に答える
8

HEAD は Web サーバーへの提案にすぎないことを覚えておく必要があります。HEAD が正しいことを行うためには、多くの場合、管理者側の明確な努力が必要です。静的ファイルApache(またはWebサーバーが何であれ)をHEADすると、多くの場合、正しいことを行います。動的ページを HEAD する場合、ほとんどのセットアップのデフォルトは、GET パスを実行し、すべての結果を収集して、コンテンツなしでヘッダーのみを送り返すことです。そのアプリケーションが 3 層 (またはそれ以上) のセットアップにある場合、その呼び出しは非常に高価になる可能性があり、HEAD コンテキストには不要です。たとえば、Java サーブレットでは、デフォルトで doHead() は doGet() を呼び出すだけです。アプリケーションをもう少しスマートにするには、開発者は doHead() を明示的に実装する必要があります (ほとんどの場合、実装しません)。

数百メガバイトの価格情報をダウンロードするために使用されるフォーチュン 100 企業のアプリに遭遇しました。変更日が変わるまでかなり定期的に HEAD リクエストを実行して、そのデータの更新をチェックします。このリクエストは、バックエンドでギガバイトのデータを含むリクエストを行うたびに、このリストを生成するためのバックエンド呼び出しを実際に行い、複数の内部サーバー間で転送することが判明しました。彼らは私たちにあまり満足していませんでしたが、ユースケースを説明するとすぐに別の解決策を思いつきました. Web サーバーに偽装するのではなく、HEAD を実装していれば、問題にはならなかったでしょう。

于 2009-04-20T22:11:52.950 に答える
4

メモリが失敗しない場合は、CURLでHEADリクエストを実行すると、HTTPプロトコルのバージョンが1.0に変更されます(これは遅く、おそらくここでは有罪です)。次のように変更してみてください。

$ch = curl_init();
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt ($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);

// Only calling the head
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); // ADD THIS

$content = curl_exec ($ch);
curl_close ($ch);
于 2009-04-20T21:41:42.087 に答える
3

以下の関数を使用して、リダイレクトされた URL を見つけました。

$head = get_headers($url, 1);

2 番目の引数は、キーを含む配列を返すようにします。たとえば、以下はLocation値を示します。

$head["Location"]

http://php.net/manual/en/function.get-headers.php

于 2011-07-23T12:47:16.087 に答える
0

これ:

curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);

ヘッダーを取得しようとしていませんでした。
上記のように、一部のデータのページ読み込みに2分かからないようにしようとしていました。
その魔法のような小さなオプションにより、2 秒に短縮されました。

于 2011-03-01T17:53:57.313 に答える