首页 > 解决方案 > 为什么使用 cURL 上传的文件在文件开头包含部分请求标头 - 如边界、Content-Type?

问题描述

我正在尝试使用 cURL 命令行实用程序将文件上传到文件托管服务。起初,我使用 Chromium 浏览器上传了一个文件,并打开了 Web 开发者控制台:在网络选项卡中,我查找了相应的行,然后单击“全部复制为 curl”。我模仿了相同的请求 - 在正确登录并附加保存的 cookie 文件后 - 使用 cURL,但是当我下载上传的文件时,不幸的是文件内容总是以几行 HTTP 标头开头,我明确发送(设置为 - H,如 Content-Type),或由 cURL 隐式添加(如边界)。

文件内容开头的示例:

--------------------------1dbea6717e57a1ab
Content-Disposition: attachment; name="files[]"; filename="data.bin"
Content-Type: application/octet-stream

<...binary file data then...>

其中行结尾是 CR/LF(十六进制查看器中的 0D0A),并且在这个不需要的标题的最前面是双 CR/LF 0D0A0D0A。

什么会导致这种奇怪的行为?似乎服务器端程序无法将二进制文件数据与标题行分开。也许我应该手动设置边界或仅使用 LF(换行,0A)作为标题的行尾?我找不到这样的 cURL 选项,它可以设置分隔标题行的字符(CR/LF <-> LF)。

我用于上传的 cURL 命令:

curl 'https://example.com/upload' -H 'Origin: https://example.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.9,hu;q=0.8' -H 'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36' -H 'Content-Type: application/octet-stream' -H 'Accept: */*' -H 'Referer: https://example.com/' -b cookie.txt -H 'Connection: keep-alive' -F "files[]=@data.bin" --compressed -L

如果我使用服务的网络上传器 - 一些 JS 库 - 文件当然可以。

如果我使用这个命令,那么它基本上可以工作,问题是服务器上的文件大小将为零。但是,当我下载文件时,它是完整的,md5sum 通过了。当我使用网络上传器时,这也不会发生,在这种情况下,服务器上的文件大小也可以。

curl 'https://example.com/upload' -H 'Origin: https://example.com' -H 'Accept-Encoding: gzip, deflate, br' -H 'Accept-Language: en-US,en;q=0.9,hu;q=0.8' -H 'User-Agent: Mozilla/5.0 (X11; Linux i686) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.106 Safari/537.36' -H 'Accept: */*' -H 'Referer: https://example.com/'  -H 'Connection: keep-alive' -b cookie.txt -F "files[]=@data.bin;type=application/octet-stream" --compressed -L

标签: curluploadmultipartboundarylinefeed

解决方案


似乎服务器端程序无法将二进制文件数据与标题行分开

是的,很可能是,服务器端程序不理解multipart/form-data-format,并认为多部分标头是实际文件的一部分。这表明服务器希望您在请求正文中上传原始文件。要让 curl 在请求正文中上传原始文件,请--data-binary @filename改用。

https://example.com/upload 的文档应该说明文件应该如何上传。


推荐阅读