如何在Windows上使用Chrome的“复制为cURL”来处理多部分/表单数据发布请求?

rdrgkggo  于 2023-03-13  发布在  Windows
关注(0)|答案(2)|浏览(580)

我正在开发一个Web应用的模块,为了触发这个模块,我需要向服务器提交一些数据,对于简单的表单,Chrome开发者工具中的Copy as cURL可以正常工作(使用msys[git]中的curl),但是对于multipart/form-data的post请求,复制的字符串在windows shell(cmd)和bash(form msys)中都不可用;复制的文本类似于:

curl "http://myserver.local" -H "Origin: http://wiki.selfhtml.org" -H "Accept-Encoding: gzip, deflate" -H "Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4" -H "User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36" -H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryntXdlWbYXAVwCIMU" -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" -H "Cache-Control: max-age=0" -H "Referer: http://wiki.selfhtml.org/extensions/Selfhtml/frickl.php/Beispiel:HTML_form-Element1.html" -H "Connection: keep-alive" --data-binary "------WebKitFormBoundaryntXdlWbYXAVwCIMU"^
"Content-Disposition: form-data; name=""area"""^

"multi"^
"line"^
"------WebKitFormBoundaryntXdlWbYXAVwCIMU--"^
"" --compressed

有什么办法可以让我用这个或者把它转换成有用的东西吗?

czq61nw1

czq61nw11#

Chrome,实际上和其他浏览器一样,在将多部分表单转换为curl命令行方面做得相当糟糕。
一个更方便的curl命令行不会使用--data-binary,而是使用--form,然后每个输入字段需要一个--form
在您的情况下,它 * 可能 * 看起来像这样(为了便于查看,在这里插入了反斜杠):

curl "http://myserver.local" \
 --compressed \
 -H "Origin: http://wiki.selfhtml.org" \
 -A "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/43.0.2357.130 Safari/537.36" \
 -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8" \
 -H "Cache-Control: max-age=0" \
 -e "http://wiki.selfhtml.org/extensions/Selfhtml/frickl.php/Beispiel:HTML_form-Element1.html" \
 -F area=[contents]

我把[contents]留在里面了,但是应该用你真正想要的area字段来替换它,如果你愿意,你也可以从一个文件传递它。
我删除了两个不必要的-H使用,并替换了两个使用直接 curl 选项。

h2 c-顶盖 curl

对未来的建议:使用curl命令行找出要重现的确切HTTP头跟踪,并将其粘贴到https://curl.se/h2c/

jgwigjjp

jgwigjjp2#

虽然Daniel Stenberg's answer显然是最好的,但作为网页开发人员,我们并不总是有时间每天手动创建几十个curl请求,如果我们不这样做,Chrome的Copy as cURL仍然可能无法上传文件。
Laravel的Symfony\Component\HttpFoundation\File\UploadedFile::getClientMimeType()没有检测到mime类型。$request->file->getMimeType()的Xdebug只显示application/x-empty。下面是my file.pdf的多部分表单域的外观:

------WebKitFormBoundaryXXXXXXXXXXXXXXXX\r\nContent-Disposition: form-data; name="file"; filename="my file.pdf"\r\nContent-Type: application/pdf\r\n\r\n\r\n

我已经尝试了所有我能想到的方法,比如filename="my file.pdf"; Content-Type: application/pdf,以及将Chrome的副本作为cURL与-F "file=@Sample Estimated Fees.pdf;type=application/pdf"组合,但是cURL不接受-F--data-raw,或者它会出错:

Warning: You can only select one HTTP request method! You asked for both POST 
Warning: (-d, --data) and multipart formpost (-F, --form).

我们不必等待curl允许我们将-F参数添加到具有指定的多部分/表单-数据边界的请求主体中,也不必等待Chrome得到修复(现在谷歌正在追赶必应的ChatGPT,这不太可能发生),我们可以使用Postman或其web version(需要注册,这涉及隐私问题):

  1. Chrome浏览器-〉开发者工具(网页检查器)-〉网络-〉右击请求-〉复制-〉复制为cURL
    1.公开 Postman
    1.单击左上角的Import按钮
    1.单击Raw Text选项卡
    1.粘贴
    1.单击Continue按钮
    1.单击Import按钮
    1.单击右上角的</>按钮以显示代码片段
    1.单击右上角的按钮或手动复制代码段
    新代码段几乎可以保证在您的平台上工作,但请注意文件必须位于运行curl的同一目录中。
    1.单击Body选项卡-〉Bulk Edit以获取用于手动构造curl -F线的键值对
    我在网上找不到任何其他方法来将文件附加到原始的多部分表单curl上。
    https://gist.github.com/z11i/fdd874573fc4956c3ee3aad164eddbfe
    Curl allows reading from stdin via - and bash提供了内置文件/dev/stdin,因此可以使用heredoc将Chrome代码片段的--data--raw部分作为一个文件传入,然后可以通过第二个json文件或其他文件传入更多参数。
{
cat << 'EOF'
------WebKitFormBoundaryXXXXXXXXXXXXXXXX\r\n..
EOF
} | curl <url> \
  -H 'Authorization: Bearer <token>' \
  -H 'Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryXXXXXXXXXXXXXXXX' \
  -F "file=@/dev/stdin;type=multipart/form-data"

相关问题