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

使用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

想问两个问题:

  1. 为什么CMD实现这么简洁,PowerShell却需要十几行代码?
  2. 怎么解决当前的JSON格式错误?

解答

一、CMD与PowerShell实现差异的原因

CMD里的curl是Windows原生的curl.exe,它用-F参数发送的是multipart/form-data格式请求——这种格式天然支持同时传递JSON数据和文件,curl会自动帮你封装请求结构,只需要按规则指定字段即可,所以看起来简洁。

而你之前写的PowerShell代码犯了两个方向错误:一是错误选择了application/json请求头(JSON格式本身不支持直接附加文件);二是对PowerShell的参数处理逻辑不熟悉。实际上PowerShell也能写成一行,只是为了可读性通常拆分多行,并非必须十几行。

二、解决PowerShell的JSON错误并实现需求

你当前报错的核心原因:

  1. 哈希表$Body不会自动转为合法JSON,直接传给Invoke-WebRequest会导致格式混乱;
  2. 即使转成JSON,application/json格式也无法携带文件;
  3. 哈希表里的"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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 03:54:28