使用PowerShell通过Discord Webhook上传文本文件报错求助
问题描述
我测试了多个在线示例都没成功,自己写的PowerShell代码如下:
$hookUrl = 'https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXXXXX' $Body = @{ 'username' = $env:username 'content' = "this is a test" "file=@C:\Users\User\Desktop\test.txt" } Invoke-WebRequest -uri $hookUrl -Method POST -Body $Body -Headers @{'Content-Type' = 'application/json'}
运行后报错:
Invoke-WebRequest : {"code": 50109, "message": "The request body contains invalid JSON."} At line:11 char:1 + Invoke-WebRequest -uri $hookUrl -Method POST -Body $Body -Headers @{' ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
而CMD用一行curl命令就能完成相同需求:
curl -F "payload_json={\"username\": \"jakoby\", \"content\": \"download me\"}" -F "file=@\"C:\Users\User\Desktop\newUser.txt\"" WEB-HOOK
想问两个问题:
- 为什么CMD实现这么简洁,PowerShell却需要十几行代码?
- 怎么解决当前的JSON格式错误?
解答
一、CMD与PowerShell实现差异的原因
CMD里的curl是Windows原生的curl.exe,它用-F参数发送的是multipart/form-data格式请求——这种格式天然支持同时传递JSON数据和文件,curl会自动帮你封装请求结构,只需要按规则指定字段即可,所以看起来简洁。
而你之前写的PowerShell代码犯了两个方向错误:一是错误选择了application/json请求头(JSON格式本身不支持直接附加文件);二是对PowerShell的参数处理逻辑不熟悉。实际上PowerShell也能写成一行,只是为了可读性通常拆分多行,并非必须十几行。
二、解决PowerShell的JSON错误并实现需求
你当前报错的核心原因:
- 哈希表
$Body不会自动转为合法JSON,直接传给Invoke-WebRequest会导致格式混乱; - 即使转成JSON,
application/json格式也无法携带文件; - 哈希表里的
"file=@C:\Users\User\Desktop\test.txt"写法不合法,哈希表需要键值对结构。
正确的做法是用multipart/form-data格式发送请求,以下是两种实现方式:
方式1:可读性优先的多行写法
$hookUrl = 'https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXXXXX' # 构造payload的JSON内容 $payload = @{ username = $env:USERNAME content = "this is a test" } | ConvertTo-Json # 发送包含文件的请求 Invoke-RestMethod -Uri $hookUrl -Method Post -Form @{ payload_json = $payload file = @{ Name = 'file' Path = 'C:\Users\User\Desktop\test.txt' } }
方式2:和CMD类似的一行写法
Invoke-RestMethod -Uri 'https://discord.com/api/webhooks/XXXXXXXXXXXXXXXXXXXX' -Method Post -Form @{payload_json = (@{username=$env:USERNAME;content="this is a test"}|ConvertTo-Json); file=@{Name='file';Path='C:\Users\User\Desktop\test.txt'}}
补充说明
- PowerShell里的
Invoke-RestMethod比Invoke-WebRequest更适合处理API请求,会自动处理JSON序列化和响应解析;如果坚持用Invoke-WebRequest,替换上述代码中的Invoke-RestMethod即可。
内容的提问来源于stack exchange,提问作者I am Jakoby
相关产品推荐
相关产品推荐

