Laravel使用cURL请求设备JSON接口返回登录页HTML问题求助
问题根因
你开启CURLOPT_FOLLOWLOCATION后,cURL默认在跳转请求时不会继续携带Authorization认证头,导致跳转后的请求没有有效身份信息,所以返回登录页HTML。
可行解决方案
方案1:添加跳转携带认证配置(PHP 7.3及以上版本推荐)
直接在原有cURL配置中新增CURLOPT_UNRESTRICTED_AUTH参数,开启跳转后继续携带认证信息的逻辑,同时可以补充Accept头指定期望返回JSON格式,避免部分接口默认返回HTML:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "$url.0.json"); curl_setopt($ch, CURLOPT_USERPWD, "$username:$password"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 40); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); // 新增两行配置 curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE); curl_setopt($ch, CURLOPT_UNRESTRICTED_AUTH, TRUE); // 可选:指定接受JSON格式响应 curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Accept: application/json' ]); $response = curl_exec($ch); $errno = curl_errno($ch); $error = curl_error($ch); $code = -1; if (!$errno) $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch);
方案2:手动处理302跳转(兼容低版本PHP)
关闭自动跳转,自行获取302响应的Location头,手动发起第二次请求并携带认证信息:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "$url.0.json"); curl_setopt($ch, CURLOPT_USERPWD, "$username:$password"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 40); curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch, CURLOPT_HEADER, 1); // 开启获取响应头 curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Accept: application/json' ]); $response = curl_exec($ch); $errno = curl_errno($ch); $code = !$errno ? curl_getinfo($ch, CURLINFO_HTTP_CODE) : -1; if ($code == 302) { // 从响应头提取跳转地址 preg_match('/Location: (.*?)\r\n/', $response, $matches); $redirectUrl = trim($matches[1] ?? ''); if ($redirectUrl) { // 手动发起跳转后的请求 $ch2 = curl_init($redirectUrl); curl_setopt($ch2, CURLOPT_USERPWD, "$username:$password"); curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch2, CURLOPT_TIMEOUT, 40); curl_setopt($ch2, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_setopt($ch2, CURLOPT_HTTPHEADER, [ 'Accept: application/json' ]); $response = curl_exec($ch2); curl_close($ch2); } } curl_close($ch);
方案3:兼容表单会话认证场景
如果以上方案都无效,说明远端设备不支持Basic Auth,采用的是账号密码提交表单的会话认证机制,按以下流程处理:
- 先请求登录提交接口,保存服务端返回的Cookie
- 再携带Cookie请求数据接口
示例代码:
$cookieFile = tempnam(sys_get_temp_dir(), 'curl_cookie'); // 第一步:提交登录请求,保存Cookie $ch = curl_init($loginUrl); // 替换为实际的登录提交地址 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'username' => $username, 'password' => $password ])); curl_setopt($ch, CURLOPT_COOKIEJAR, $cookieFile); // 保存Cookie到临时文件 curl_exec($ch); curl_close($ch); // 第二步:携带Cookie请求数据接口 $ch = curl_init("$url.0.json"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_COOKIEFILE, $cookieFile); // 读取之前保存的Cookie curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Accept: application/json' ]); $response = curl_exec($ch); curl_close($ch); // 用完删除临时Cookie文件 unlink($cookieFile);
内容的提问来源于stack exchange,提问作者P.Lee
相关产品推荐
相关产品推荐

