【问题标题】:API call works in browser, but reports (incorrect?) redirect when called via PHP curlAPI 调用在浏览器中有效,但通过 PHP curl 调用时报告(不正确?)重定向
【发布时间】:2013-06-09 14:18:54
【问题描述】:

我必须构建一个脚本,将我们从合作伙伴公司的 API 获得的 JSON 转换为我们当前的软件无需太多更改即可读取的 Xml 文件。听起来很简单,API 也相对简单——只是我调用它时似乎无法得到结果,即使在浏览器中运行完全相同的调用也是如此。

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

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

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

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

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

函数 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', '接受: */*', '接受语言:en-us,en;q=0.5', '接受字符集: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); 返回$输出; } $用户名 = '#用户名'; $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 - 文档已移至此处”。在浏览器中或使用 curl 时,遵循此操作绝对不会提供任何输出。

编辑: 好的,这是请求头:

(Request-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
接受语言 de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
接受编码 gzip,放气
DNT 1
饼干疯狂统计=42d1e7eb3c1dbcc59dd28e986ba9ceb3; 5991e5c00fce8acb72465bbca79260ecb=bc800030fa14aff2c5f726f1cfe3ffe7
基本授权 fzBob66lajgybiRqYTglbGE5p2FtdTqmQmCmYZk=
连接保持活动
缓存控制 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;到期=格林威治标准时间 2013 年 12 月 16 日星期一 10:01:14;路径=/
内容长度 602
保活超时=5,最大值=100
连接保活
内容类型 text/html

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

【问题讨论】:

  • 在您发出成功的 API 请求时复制浏览器的请求标头和服务器的响应标头并附加到此问题。它可能会为正在发生的事情提供线索。
  • 完成。我还应该提到,我已经尝试过保存 cookie,但没有任何区别。
  • 你是故意在 curl 和浏览器请求中使用不同的主机还是一个错字?
  • 这是一个错误 - 我已经编辑了我的问题。我现在收到 401 Authorization Required 响应,所以我设置用户名和密码的方式可能有些问题,但是什么?

标签: php json api curl


【解决方案1】:

我现在觉得自己很蠢,有两个原因:

  1. 尤金指出的错误,即我在标头中使用了错误的主机。
  2. 然后我花了半天时间找出授权失败的原因,阅读有关 curl 函数和所有内容的文档。现在我发现了错误:我的密码包含§ 符号,并且发送错误的密码只是因为编码。我在密码周围放了一个utf8_decode,现在它就像一个魅力。又一个谜团解开了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-08
    • 2017-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-19
    • 1970-01-01
    相关资源
    最近更新 更多