使用PHP cURL上传视频至Azure Blob存储遇InvalidHeaderValue错误求助
解决Azure Blob存储上传时的InvalidHeaderValue错误
问题概述
需要编写单函数PHP脚本,通过cURL使用认证密钥将本地video.mp4上传至Azure Blob容器,不使用SDK或第三方库。调用uploadFileToAzureBlob时触发InvalidHeaderValue错误,报错详情:
InvalidHeaderValue The value for one of the HTTP headers is not in the correct format. RequestId:798508a1-701e-0055-0e82-efab9f000000 Time:2023-09-25T07:34:50.5926245ZContent-Length-1
错误原因分析
从报错和代码来看,核心问题集中在HTTP头冲突、参数不一致及格式错误:
- 同时设置
Transfer-Encoding: chunked和Content-Length头,Azure Blob不允许这两个头共存 - 请求URL缺失文件后缀(仅用
PATHINFO_FILENAME导致文件名不完整) - 文件大小参数混乱(同时使用
filesize()和$fileArray["size"],且CURLOPT_INFILESIZE与Content-Length可能冲突) Authorization头可能不符合Azure Shared Key的标准格式(需为SharedKey accountname:signature)x-ms-date的时区格式未严格遵循HTTP标准CURLOPT_CUSTOMREQUEST: PUT与CURLOPT_UPLOAD: true同时设置导致请求方法冲突
修复方案
- 移除
Transfer-Encoding: chunked头,上传文件时使用Content-Length更符合Azure要求 - 拼接完整文件名(包含后缀)到请求URL
- 统一文件大小取值,确保
Content-Length与实际文件大小一致,移除冗余的CURLOPT_INFILESIZE设置 - 验证
Authorization头格式为SharedKey <存储账户名>:<签名值> - 修正
x-ms-date的日期格式为标准HTTP格式 - 移除
CURLOPT_CUSTOMREQUEST: PUT,仅保留CURLOPT_UPLOAD: true(该选项隐含PUT请求)
修正后的完整代码
function uploadFileToAzureBlob($key, $container, $azureUrl, $uploadedFile, $fileArray){ // 拼接完整文件名(包含后缀) $fileInfo = pathinfo($uploadedFile["file"]); $url = $azureUrl . $container . "/" . $fileInfo["filename"] . "." . $fileInfo["extension"]; $fileHandle = fopen($uploadedFile["file"], 'r'); $ch = curl_init($url); // 启用UPLOAD选项,隐含PUT请求方法 curl_setopt($ch, CURLOPT_UPLOAD, true); curl_setopt($ch, CURLOPT_INFILE, $fileHandle); $fileSize = filesize($uploadedFile["file"]); $headers = array( "x-ms-blob-type" => "BlockBlob", "x-ms-version" => "2017-11-09", "x-ms-date" => gmdate('D, d M Y H:i:s \G\M\T'), "Content-Type" => $fileArray["type"], "Content-Length" => $fileSize, "Authorization" => $key ); // 格式化HTTP头为"Key:Value"格式 $formattedHeaders = array_map(function($v, $k){ return "$k:$v"; }, $headers, array_keys($headers)); curl_setopt($ch, CURLOPT_HTTPHEADER, $formattedHeaders); // 禁用SSL验证(生产环境建议启用) curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 捕获响应内容而非直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); $curlInfo = curl_getinfo($ch); fclose($fileHandle); curl_close($ch); // 调试用输出(可按需移除) echo json_encode($uploadedFile) . "<br>"; echo json_encode($fileArray) . "<br>"; echo $fileSize . "<br>"; echo $url . "<br>"; echo json_encode($headers) . "<br>"; echo $fileArray["size"] . "<br>"; echo json_encode($response) . "<br>"; echo "curl:::: " . json_encode($curlInfo) . "<br>"; return $response; }
额外注意事项
- 生产环境请启用
CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST,保障SSL连接安全 - 确认
$key参数是正确的Azure Shared Key签名,格式必须为SharedKey <YourStorageAccount>:<YourGeneratedSignature> - 若文件超过100MB,建议改用块上传方式,避免单次上传失败
内容的提问来源于stack exchange,提问作者Lakshyya Kothari
相关产品推荐
相关产品推荐

