cURL 使页面永远加载,然后网关超时
Posted
技术标签:
【中文标题】cURL 使页面永远加载,然后网关超时【英文标题】:cURL makes page load forever, then gateway timed out 【发布时间】:2021-01-21 19:36:58 【问题描述】:我正在使用第三方 API,当您出错时它会返回 400 HTTP STATUS。 使用 POSTMAN 时,400 HTTP 错误页面按预期显示,但是当使用 php 的 cURL 时,页面只加载大约一分钟,然后它给了我“504 - 网关超时”,我需要关闭浏览器才能再次访问该页面。 当 cURL 请求有效(API 返回 200 OK)时,它可以正常工作。
我的问题是,为什么 cURL 给出 504 错误而不是 400? 为什么它忽略了 CURLOPT_CONNECTTIMEOUT 和 CURLOPT_TIMEOUT?
以下是我的 cURL 代码($token、$payload 和 $config 变量均已声明且有效):
$ch = curl_init("https://api.mercadolibre.com/items?access_token=$token");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"User-Agent: Alcavie/" . $config['version'],
"Accept: application/json",
"Content-Type: application/json",
//"Accept-Encoding: gzip, deflate, br",
//"Connection: keep-alive"
));
$error = false;
try
$result = curl_exec($ch);
$resultJson = json_decode($result);
catch(\Exception $e)
var_dump($e);
$error = true;
exit;
curl_close($ch);
【问题讨论】:
504 Gateway Timeout 是由该 API 的后端服务器发出的,不在请求中,与 408 Request Timeout 不同。我猜标题可能是错误的,请检查 Postman 拥有的 User-Agent、令牌或其他配置,并且 curl 没有配置。 【参考方案1】:API 可能会在两者之间发送 HTTP302
,如果是这样,您要么需要两个请求,要么使用 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
告诉 cURL 跟随重定向HTTP504
表示客户端没有及时对先前的 HTTP 标头做出反应;HTTP504
可能还有其他原因,但这是最常见的原因之一。邮递员不足以正确测试(我根本不使用它);最好使用网络浏览器,点击F12
并勾选“保留日志”复选框...然后您可以清楚地看到哪些 HTTP 标头正在连续发送。
这对调试也很有用:curl_setopt($ch, CURLOPT_HEADER, true);
【讨论】:
即使在设置 FOLLOWLOCATION 之后,我也得到了相同的结果:几乎无限加载,然后在我的浏览器中出现 504 错误。而 CURLOPT_HEADER 只是使 cURL 失败 btw @Thiago 此选项应列出所有发送和接收的标头。确保你使用一个理智的环境。 curl.haxx.se/libcurl/c/CURLOPT_HEADER.html ...而且“只是让它失败”根本不是错误描述,因为它几乎没有无缘无故地失败。如果您只是采用简单的 HTML 表单并将其发布,那么它应该可以在网络浏览器中进行测试。改进 cURL 错误处理也可能有意义,因为您没有遵循那里的默认程序;var_dump($e)
没用....使用curl_error($ch)
,以免忽略最终的错误。
另见developers.mercadolibre.com/listing-introduction ...有效载荷可能是错误的。抱歉,我对此一无所知,只能参考:api.mercadolibre.com/items#options ... GET /items
只是给了我resource not found
(可能是因为它需要一个 POST)。通常 cURL 只是模拟网络浏览器,这就是为什么人们可以使用网络浏览器来确定要模拟什么。
重点是代码连catch都没命中,所以curl_error也没用;当我添加 CURLOPT_HEADER 时,“如果失败就成功”发生,它给我同样的加载,然后 504,即使有效负载是正确的(我的意思是:在没有 CURLOPT_HEADER 的情况下工作)API 的文档是葡萄牙语,所以你不理解它是正常的。我需要捕捉这些 API 错误,因为客户端可能有时会犯错误,并且给他们一个“504 - 网关超时”页面根本不好
你能访问任何使用 GET 的路由吗,例如。列出那些项目? Exception
不一定要抛出,但如果有错误,可以从 cURL 句柄中获取。我的代码通常看起来没什么不同(除了错误处理),但我通常只是调用curl_init()
,然后设置 URL 和选项。启用选项CURLOPT_HEADER
后,您通常会得到类似于以下内容的输出:***.com/a/3252889/549372 ...这对于调试非常重要。以上是关于cURL 使页面永远加载,然后网关超时的主要内容,如果未能解决你的问题,请参考以下文章
在 Google Colab 中运行 TensorFlow 2 setup.py 会永远加载然后超时
空闲超时后,由 Keycloak 客户端应用程序保护重定向到登录页面。应用程序位于应用程序网关后面
如何使 libcurl C++ 调用超时和/或知道调用中何时发生超时