API调用在浏览器中工作,但在通过PHP curl调用时报告(不正确?)重定向

时间:2013-06-13 08:54:06

标签: php json api curl

我必须构建一个脚本,将我们从合作伙伴公司的API获得的JSON转换为我们当前软件可以读取的Xml文件,而不会发生太大变化。听起来很简单,API也相对简单 - 只是当我调用它时,我似乎无法得到结果,即使完全相同的调用在浏览器中有效。

当我在浏览器中调用API函数时,我得到一个很好的小JSON对象作为回报,但是当我尝试通过我的PHP脚本中的curl调用完全相同的URL时,我只获得了302 - Moved响应。奇怪的是,就我所见,重定向不会在浏览器中发生,如果我遵循它,它也根本不包含任何内容(但它确实属于另一家公司)。

我开始怀疑它与授权有关。虽然我已经检查并重复检查了大约一百万次的用户名和密码,但我注意到如果我故意使用错误的用户名/密码组合,我会得到相同的结果。我注意到的另外几件事:

  • IE 9接受登录就好了
  • Firefox在接受密码之前经常要求密码两到三次,并向我显示JSON结果
  • Opera和Chrome根本不接受登录。这绝对不是拼写错误 - 我正在复制和粘贴工作密码。

现在,我正试图与另一家公司的技术人员进行联系,以便与之讨论,但我开始认为这可能是其他人可能遇到的更普遍的问题,所以我决定在这里发布这个问题。以下是我脚本的摘录。我现在几乎可以肯定我做了一些愚蠢的事情(或者愚蠢地做了我应该做的事情),如果我能在互联网上匿名地对自己进行骚扰,而不是让自己与现实生活中的技术人员相媲美,那就太好了。 / p>

编辑:在我的脚本中更改了主机。

function curl_download($url, $username, $password)
{
    $http_headers = array(
                    'Host: www.myapidomain.com',
                    'User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:6.0.2) Gecko/20100101 Firefox/6.0.2',
                    'Accept: */*',
                    'Accept-Language: en-us,en;q=0.5',
                    'Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7',
                    'Connection: keep-alive'
                  );

    $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); Tried with and without that
    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);

    return $output;
}

$username = '#username';
$password = '#password';
$url = $api_details.$myID; //something like example.com/api/?id=1234

//tried it with a context and file_get_contents once just for the kicks, but didn't work either
// $context = stream_context_create(array(
    // 'http' => array(
        // 'header'  => "Authorization: Basic " . base64_encode("$username:$password")
    // )
// ));
// $result = file_get_contents($url, false, $context);
$result = curl_download($url, $username, $password);
echo 'JSON: '.$result; //result is "302 Found - document has moved here". Following this gives absolutely no output in the browser or when following with curl.

编辑: 好的,这是请求标题:

(Request-Zeile)    GET /api/?id=100100 HTTP/1.1
Host    www.myapidomain.com
User-Agent  Mozilla/5.0 (Windows NT 6.0; rv:21.0) Gecko/20100101 Firefox/21.0
Accept  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, deflate
DNT 1
Cookie  MaD-Stats=42d1e7eb3c1dbcc59dd28e986ba9ceb3; 5991e5c00fce8acb72465bbca79260ecb=bc800030fa14aff2c5f726f1cfe3ffe7
Authorization   Basic fzBob66lajgybiRqYTglbGE5p2FtdTqmQmCmYZk=
Connection  keep-alive
Cache-Control   max-age=0

这里是响应标题:

(Status-Zeile) HTTP/1.1 200 OK
Date    Thu, 13 Jun 2013 10:01:13 GMT
Server  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=Mon, 16-Dec-2013 10:01:14 GMT; path=/
Content-Length  602
Keep-Alive  timeout=5, max=100
Connection  Keep-Alive
Content-Type    text/html

EDIT2: 所以,为了回应Eugene的问题,我在curl请求中设置了正确的主机。现在我得到401响应,这更有意义。我设置登录信息的方式有问题吗?

1 个答案:

答案 0 :(得分:1)

我现在感到愚蠢,原因有两个:

  1. Eugene指出的错误,即我在标题中使用了错误的主机。
  2. 然后,我花了半天时间弄清楚授权失败的原因,阅读有关卷曲功能和所有内容的文档。现在我发现错误:我的密码包含§符号,并且仅因编码而发送了错误的密码。我在我的密码周围添加了utf8_decode,现在它就像一个魅力。另一个谜团解决了。