0

パートナー企業の API から取得した JSON を、現在のソフトウェアがほとんど変更せずに読み取れる Xml ファイルに変換するスクリプトを作成する必要があります。非常に単純に聞こえますが、API も比較的単純です。まったく同じ呼び出しがブラウザーで機能するにもかかわらず、呼び出したときに結果が得られないように見えるだけです。

ブラウザーで API 関数を呼び出すと、小さな JSON オブジェクトが返されますが、PHP スクリプトで curl を介してまったく同じ URL を呼び出そうとすると、302 - Moved 応答しか返されません。奇妙なことに、私が見る限りブラウザでリダイレクトが発生せず、それをたどってもコンテンツがまったく含まれていません(ただし、他の会社に属しています)。

私はそれが認可と関係があるのではないかと疑い始めています。ユーザー名とパスワードを約 100 万回確認して再確認しましたが、意図的に間違ったユーザー名とパスワードの組み合わせを使用しても同じ結果になることに気付きました。私が気づいた別のいくつかのこと:

  • IE 9はログインを問題なく受け入れます
  • Firefox は、パスワードを受け入れる前にパスワードを 2、3 回要求し、JSON の結果を表示することがよくあります。
  • Opera も Chrome もログインをまったく受け付けません。間違いなくタイプミスではありません - 作業用パスワードをコピーして貼り付けています。

今、私は他の会社の技術者と連絡を取り、この件について話し合おうとしていますが、これはより一般的な問題であり、他の人も同様に遭遇する可能性があると考え始めているので、そうすることにしましたこの質問をここに投稿してください。以下は私のスクリプトからの抜粋です。私は今では、自分が愚かなことをしている (または愚かなことにすべきことをしていない) ことをほぼ確信しており、実際の技術者に恥をかかせるのではなく、インターネット上で匿名で自分を恥じることができれば幸いです。

編集:スクリプトでホストを変更しました。

function curl_download($url, $username, $password)
{
    $http_headers = 配列(
                    'ホスト: www.myapidomain.com',
                    'ユーザーエージェント: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2',
                    '承認: */*'、
                    'Accept-Language: en-us,en;q=0.5',
                    'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7',
                    「接続: キープアライブ」
                  );

    $ch = curl_init();    

    curl_setopt($ch, CURLOPT_HTTPHEADER, $http_headers);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    // curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); それの有無にかかわらず試してみました
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

    $output = curl_exec($ch);

    curl_close($ch);

    $出力を返します。
}

$username = '#ユーザー名';
$password = '#パスワード';
$url = $api_details.$myID; //example.com/api/?id=1234 のようなもの

//念のため、コンテキストと file_get_contents を使用して一度試してみましたが、どちらも機能しませんでした
// $context = stream_context_create(array(
    // 'http' => 配列(
        // 'header' => "承認: 基本" . base64_encode("$ユーザー名:$パスワード")
    // )
// ));
// $result = file_get_contents($url, false, $context);
$result = curl_download($url, $username, $password);
echo 'JSON: '.$result; //結果は「302 Found - ドキュメントはここに移動しました」。これに続いて、ブラウザーで、またはcurlでフォローしたときに、まったく出力が得られません。

編集:さて、ここにリクエストヘッダーがあります:

(リクエスト-Zeile) GET /api/?id=100100 HTTP/1.1
ホスト www.myapidomain.com
ユーザーエージェント Mozilla/5.0 (Windows NT 6.0; rv:21.0) Gecko/20100101 Firefox/21.0
text/html、application/xhtml+xml、application/xml を受け入れる;q=0.9,*/*;q=0.8
Accept-Language de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding gzip、デフレート
DNT 1
Cookie MaD-Stats=42d1e7eb3c1dbcc59dd28e986ba9ceb3; 5991e5c00fce8acb72465bbca79260ecb=bc800030fa14aff2c5f726f1cfe3ffe7
認証基本 fzBob66lajgybiRqYTglbGE5p2FtdTqmQmCmYZk=
接続キープアライブ
Cache-Control max-age=0

そしてここに応答ヘッダーがあります:

(ステータス-Zeile) HTTP/1.1 200 OK
日付 2013 年 6 月 13 日(木)10:01:13 GMT
サーバー Apache/2.2.23 (FreeBSD) PHP/5.2.17 mod_ssl/2.2.23 OpenSSL/1.0.1c
X-Powered-By PHP/5.2.17
Set-Cookie MaD-Stats=76d1a7eb2c1dbacfcdd2e5986b39ceb3; expires=2013 年 12 月 16 日月曜日 10:01:14 GMT; パス=/
コンテンツの長さ 602
キープアライブ タイムアウト = 5、最大 = 100
接続キープアライブ
コンテンツ タイプ テキスト/html

Edit2: それで、Eugene の質問に答えて、curl リクエストに正しいホストを設定しました。これで、401 応答が得られました。これは、もう少し理にかなっています。ログイン情報を設定する方法に何か問題がありますか?

4

1 に答える 1

1

2つの理由から、私は今、愚かだと感じています:

  1. Eugene が指摘したエラー、つまり、ヘッダーで間違ったホストを使用したというエラーです。
  2. 次に、認証が失敗した理由を理解するのに半日を費やし、curl 関数とすべてに関するドキュメントを読みました。ここで、エラーが見つかりました。パスワードに§記号が含まれており、エンコードが原因で間違ったパスワードが送信されました。utf8_decode私は自分のパスワードの周りに置き、今では魔法のように機能します. また謎が解けました。
于 2013-06-13T15:04:15.237 に答える