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

使用Invoke-WebRequest提交multipart表单报Content-Type异常如何解决?

这个问题不只是Content-Type请求头的问题,同时存在多个隐藏错误,具体问题和修复方案如下:

1. 错误设置Content-Length请求头

你在$Headers中手动设置的Content-Length值仅为上传文件本身的大小,并不是整个multipart请求体的总长度,这会直接触发请求校验失败。就算添加了-SkipHeaderValidation参数,服务端收到的请求内容不完整,也会返回错误。
修复方案:直接删除$Headers['Content-Length'] = $Item.Length这一行,Invoke-WebRequest会自动计算并填充正确的Content-Length请求头,无需手动设置。

2. 二进制文件转UTF-8字符串会导致文件损坏

你使用[System.Text.Encoding]::GetEncoding('UTF-8').GetString($fileBytes)将二进制文件内容转码为UTF-8字符串的逻辑是错误的,非文本类型的二进制文件会存在大量不符合UTF-8编码规则的字节,转码过程中会出现乱码、字节丢失,最终上传的文件无法正常打开。
修复方案:直接构造字节数组格式的请求体,不要对二进制文件内容做字符串转码。

3. 字符串拼接请求体存在编码问题

你直接拼接字符串作为请求体,PowerShell中的字符串默认采用UTF-16LE编码,直接传给Invoke-WebRequest时会被自动转码,导致请求体格式错乱。
修复方案:将所有请求内容统一转成UTF-8字节数组后再拼接,作为请求体传入。

4. 边界格式优化

你当前的边界写法本身不会触发Content-Type报错,不过按照multipart/form-data规范可以简化写法:ContentType中的boundary值不需要包含前后的横杠,请求体中的分隔符统一使用--$boundary,结束分隔符使用--$boundary--,避免边界格式歧义。


修复后的参考代码

$GUID = (New-Guid).Guid
$boundary = $GUID
$ContentType = "multipart/form-data; boundary=`"$boundary`""
$Item = Get-Item -Path $Path
$LF = "`r`n"
$encoding = [System.Text.Encoding]::UTF8

$bodyParts = New-Object System.Collections.Generic.List[byte[]]

# 添加上传文件名字段
$fileNamePart = @"
--$boundary
Content-Disposition: form-data; name="fileName"

$($Item.Name)
"@
$bodyParts.Add($encoding.GetBytes($fileNamePart))

# 添加文件内容字段
$fileHeader = @"

--$boundary
Content-Disposition: form-data; name="file"; filename="$($Item.Name)"
Content-Type: application/octet-stream

"@
$bodyParts.Add($encoding.GetBytes($fileHeader))
$bodyParts.Add([System.IO.File]::ReadAllBytes($Path))

# 添加share字段
$sharePart = @"

--$boundary
Content-Disposition: form-data; name="share"

$($Share ? 'yes' : 'no')
"@
$bodyParts.Add($encoding.GetBytes($sharePart))

# 添加category字段
$categoryPart = @"

--$boundary
Content-Disposition: form-data; name="category"

$CategoryId
"@
$bodyParts.Add($encoding.GetBytes($categoryPart))

# 添加结束边界
$endBoundary = @"

--$boundary--
"@
$bodyParts.Add($encoding.GetBytes($endBoundary))

# 拼接所有字节为最终请求体
$finalBody = [System.Linq.Enumerable]::SelectMany($bodyParts, [Func[byte[], byte[]]]{$_}).ToArray()

Invoke-WebRequest -Uri $Uri -Method Post -Body $finalBody -Headers $Headers -ContentType $ContentType -SkipHeaderValidation

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 23:57:03