DEBUG.WIKI
V.PS:让项目靠近用户,亚太、欧洲、北美 KVM VPS
IPPeak:从目标地区访问网页,住宅代理、SEO 监测、广告验证
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国

curl -F 上传后服务端收不到文件,只收到文件名

multipart 请求成功发出却没有附件时,检查 -F 的值是否缺少 @,并核对服务端字段名与本地读取路径。

curl 使用 -F 'file=report.html' 提交后,服务端文件字段为空,或者只收到一段 report.html 文本。请求里已有 multipart/form-data,也不代表 curl 已读取本地文件:-F 的值前是否带 @,决定了它的含义。

这里讨论要求 multipart 文件字段的 HTTP 上传接口。把整个请求体当作文件内容的接口,以及 PUT 原始文件上传,需要另外按接口格式处理。

普通字符串不会自动成为附件

下面是未读取文件的示例:

curl -F 'file=report.html' 'https://example.com/upload'

它发送名为 file 的普通字段,值就是 report.html。curl 不会根据文件扩展名或本地存在同名文件,自动把这个值变成附件。

如果接口要求 file 字段携带文件,写成以下形式。路径和域名需要替换,运行 curl 的账户必须能读取该文件:

curl -F 'file=@/path/to/report.html' \
  'https://example.com/upload'

@ 告诉 curl 读取指定文件,并把它作为带 filename 的上传部分。-F 默认使用 POST,也会构造 multipart 的分隔符,不需要额外写 -X POST 或手工拼接 boundary。

这里的 file 是接口字段名,不是 curl 的保留字段。服务端期待 document 或 fieldNameHere 时,应更换左侧名称,否则即使上传了文件,也可能被后端忽略。

@、< 和普通值的区别

如果接口需要文本字段,内容从文件中读取,可以使用 <:

curl -F 'description=</path/to/description.txt' \
  -F 'file=@/path/to/report.html' \
  'https://example.com/upload'

这会把 description 文件的内容作为字段值,file 仍为附件。不要把 < 和 @ 混用后,再通过重命名字段强迫后端把文本字段当附件。

如果本来就要发送以 @ 开头的普通字符串,可用 --form-string,防止 curl 将其解释为本地文件。原始文件请求体的 --data-binary @文件 则不负责构造 multipart 表单;选择它需要接口明确支持该请求格式。

加上 @ 后,仍要检查哪里出错

curl 若报读取本地文件失败,先核对实际工作目录、文件路径和读取权限。该路径属于执行 curl 的机器;它不是服务器上的路径。示例把完整选项用引号包住,防止 shell 把空格等字符拆成不同参数;Windows 的命令解释器需要使用对应的引号规则。

curl 成功发出请求,但后端仍返回空文件时,核对字段名、接口是否接收 multipart、上传限制和认证状态。若接口还要求单个附件的媒体类型,可以按要求在表单值后指定 ;type=text/html。不能把整个 multipart 请求的 Content-Type 改成 text/html 来替代附件类型。

上传会在服务端创建或修改内容。排查时使用获准的测试接口和无敏感信息的小文件,按该服务提供的方式清理测试记录;不要把重复上传当作无影响的读操作。

成功标准是服务端在正确字段下收到附件、文件名和内容符合预期,并返回接口定义的成功响应。仅看到 Content-Type: multipart/form-data 或 curl 没有本地错误,都不足以确认上传已经被业务端接收。