javascript - 为什么 curl 在收到早期响应时会提前终止对我的服务器的 http 请求,但来自我的浏览器前端的 http 请求却没有?
问题描述
我的 API 服务器中有一个接受文件上传的 https 路由。对上传有一些验证,例如,如果查询参数之一无效,则服务器会在使用整个请求正文(可能非常大)之前拒绝上传。
当我使用 curl(或来自 Insomnia,我认为它只是在后台使用 curl)对该 API 运行请求时,并且服务器在消耗整个主体之前返回响应时,curl 终止而不继续上传数据,即使它没有继续上传数据发送了整个有效载荷。
卷曲命令:
curl --request POST \
--url 'https://api.example.com/v0/projects/38/media?filename=somethingInvalid' \
--header 'content-type: video/mp4' \
--cookie session=orMaybeIAmInvalid \
--data '<gigantic chunk of binary here>'
这在一秒钟内终止,服务器返回 400 并带有一些响应,例如your stuff is wrong yo
. 但是,如果查询参数有效,则上传大约需要 5 分钟。所以这一切都按预期工作:我不想让用户等待几分钟和几分钟的 400 根本不基于文件的内容。
相同的请求与我的前端 Web 应用程序具有相反的行为。如果我使用相同的配置运行 xmlhttprequest 请求,即使 Web 服务器已达到尝试返回 400 并且不再关心正在上传的请求正文的程度,浏览器也会在解析之前持续运行 5 分钟它已收到 400。这是为什么呢?
我说“它试图在哪里返回 400”,因为我不确定底层技术是如何在这里工作的。我有,在我的内置游戏框架的网络服务器中,这条线只是返回 400:
if (stuff.isInvalid()) {
return completedFuture(badRequest("your stuff is wrong yo"));
}
但是,想想看,考虑到此时请求正文还没有被完全消耗掉,我真的很惊讶这对 curl 完全有效。因此,尽管我在问“为什么这个浏览器请求不按我想要的方式工作”,但我也在问我需要做哪些特定的研究途径来了解这里发生了什么。
解决方案
听起来像是curl
在发送请求的同时检查响应,并且在完成发送请求之前注意到响应已经发生。这不是正常的网络服务器行为,显然它将其视为不需要完成请求的意思。
浏览器的逻辑不同,它直到完成发送整个请求后才开始从网络读取。
当查询参数有效时,应等到post数据全部接收完毕后再发送响应,然后curl
才不会终止请求。这仍然允许您异步完成处理。
推荐阅读
- angular - Aspnetboilerplate Angular 文件上传
- c - 即使文件存在,访问(路径,标志)也返回 0
- c - 在 C 中使用 pthread 和并发的 Segfault
- elasticsearch - 从数组内容中进行 Elasticsearch 搜索
- java - 声明新的 lunchBag 对象时出现“错误:找不到符号”?
- javascript - 是否有可能通过仅使用 CSS 和 HTML 将鼠标悬停来制作一个将消失的组件?
- java - 将对象与 JSON 相互转换
- liquidsoap - Liquidsoap 无法将数据写入主机:write() 错误中的管道损坏
- ios - 检查是否下载了应用程序的回调或背景任务?
- javascript - 呃!代码 ELIFECYCLE - 执行 TodoMVC 时出错