You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP请求海康NVR带认证图片URL返回401,浏览器/wget可正常访问

海康威视NVR PHP请求401错误解决方案

原因定位

海康威视ISAPI接口对HTTP认证请求的格式要求较严格,同时Apache运行的PHP环境可能存在授权头被拦截、参数转义异常的问题,常规的Basic Auth写法无法匹配设备的校验规则。

可直接复用的修复方案

方案1:cURL适配写法(优先级最高,兼容性最好)

需要严格按照海康设备要求配置cURL参数,不要提前拼接Authorization头,让cURL自动响应设备的401质询:

<?php
$url = 'http://192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080';
$username = 'admin';
$password = '441e3!';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 关键配置:指定用Basic认证,且允许cURL响应401质询
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password");
// 忽略SSL证书校验,http请求无影响
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
// 允许跟随设备返回的302跳转
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
// 禁止自动发送Expect头,海康设备部分版本不兼容该头
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:'));

$output = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if($httpCode == 200) {
    // 输出或保存图片
    header('Content-Type: image/jpeg');
    echo $output;
} else {
    echo "请求失败,状态码:".$httpCode;
}
?>

方案2:修复file_get_contents上下文写法

如果要使用file_get_contents,需要手动构造严格符合格式的Authorization头,同时确保Apache没有拦截授权头:

  1. 先在Apache站点配置或.htaccess中添加规则,放行Authorization头:
SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
  1. PHP代码写法:
<?php
$url = 'http://192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080';
$username = 'admin';
$password = '441e3!';
$auth = base64_encode("$username:$password");

$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'header' => [
            'Authorization: Basic ' . $auth,
            'Expect:'
        ],
        // 跟随重定向时保留认证头
        'follow_location' => 1,
        'max_redirects' => 3
    ]
]);

$output = file_get_contents($url, false, $context);
if($output !== false) {
    header('Content-Type: image/jpeg');
    echo $output;
}
?>

额外验证步骤

如果上述方案仍失效,可对比请求头差异定位问题:

  • 执行wget时添加-d参数打印完整请求头:wget -d "http://admin:441e3!@192.168.1.90/ISAPI/Streaming/channels/201/picture?videoResolutionWidth=1920&videoResolutionHeight=1080"
  • 在PHP的cURL参数中添加curl_setopt($ch, CURLOPT_VERBOSE, true);打印请求细节,核对Authorization头、请求方法、其他头是否和wget一致

注意:不要把用户名密码直接拼接在URL中传递给PHP的请求方法,PHP高版本会对URL中的特殊字符做转义,反而会导致认证失败。

内容的提问来源于stack exchange,提问作者ovisopa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 17:09:01