繁体   English   中英

使用 XHR 和分块传输编码的 HTTP POST

[英]HTTP POST using XHR with Chunked Transfer Encoding

我有一个 REST API,它通过 HTTP Post 接受音频文件。 API 支持 Transfer-Encoding: 分块请求标头,以便文件可以在从客户端上运行的记录器创建时分块上传。 这样服务器就可以在文件到达时开始处理文件以提高性能。 例如:

HTTP 1.1 POST .../v1/processAudio

传输编码:分块

[Chunk 1 256 Bytes](服务器到达时开始处理)

[块 2 256 字节]

[块 3 256 字节]

...

音频文件通常很短,大小在 10K 到 100K 左右。 我有可以工作的 C# 和 Java 代码,所以我知道 API 可以工作。 但是,我似乎无法使用 javascript 在浏览器中进行录制和上传。

这是我的测试代码,它使用 Transfer-Encoding 对 localhost 执行 POST:

 <html> <script type="text/javascript"> function streamUpload() { var blob = new Blob(['GmnQPBU+nyRGER4JPAW4DjDQC19D']); var xhr = new XMLHttpRequest(); // Add any event handlers here... xhr.open('POST', '/', true); xhr.setRequestHeader("Transfer-Encoding", "chunked"); xhr.send(blob); } </script> <body> <div id='demo'>Test Chunked Upload using XHR</div> <button onclick="streamUpload()">Start Upload</button> </body> </html>

问题是我在 Chrome 中收到以下错误

拒绝设置不安全的标题“传输编码”

streamUpload @uploadTest.html:14 onclick @uploadTest.html:24

查看 XHR 文档后,我仍然感到困惑,因为它没有谈论不安全的请求标头。 我想知道 XHR 是否可能不允许或实现Transfer-Encoding: chunked for HTTP POST?

我查看了使用多个 XHR.send() 请求和 WebSockets 的变通方法,但这两种方法都不受欢迎,因为它需要对已经到位、简单、稳定且有效的服务器 API 进行重大更改。 唯一的问题是我们似乎无法通过 Transfer-Encoding: chunked request header 从带有 psedo-streaming 的浏览器 POST。

任何想法或建议都会非常有帮助。

正如评论中提到的那样,您不允许设置该标头,因为它由用户代理控制。

有关完整的标头集,请参阅4.6.2 W3C XMLHttpRequest Level 1中的setRequestHeader()方法 ,并注意Transfer-Encoding是由用户代理控制的标头之一,以便让它控制传输的这些方面。

  • 接收字符
  • 接受编码
  • 访问控制请求报头
  • 访问控制请求法
  • 连接
  • 内容长度
  • 曲奇饼
  • COOKIE2
  • 日期
  • DNT
  • 期望
  • 主办
  • 活着
  • 起源
  • 引荐
  • TE
  • 预告片
  • 传输编码
  • 升级
  • 用户代理
  • 通过

WhatWG Fetch API生活标准中有类似的列表。 https://fetch.spec.whatwg.org/#terminology-headers

正如其他回复已经提到的,您不能自己设置“传输编码”标头。

但是,您实际上也不需要使用 HTTP 分块传输编码来增量地将文件流式传输到您的服务器并立即开始处理它的一部分。 常规的 HTTP POST 就可以很好地解决这个问题。 即使它是作为单个 HTTP 请求传输的,我相信流/分块魔术会在 TCP 级别发生(如果我对魔术具体发生的地方有误,欢迎其他人纠正我)。 我可以确认这是有效的,因为我已经在后端使用 node.js 和 Express 完成了它。 我相信它可能也适用于其他服务器端技术。

HTTP 分块传输编码仅在您不知道将要发送的流的大小(例如实时视频、视频电话会议、远程桌面会话、聊天等)时才有用。 对于这些情况,WebSockets 是解决相同问题的更广泛部署的解决方案:https ://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API

对于您的用例,如果您事先知道文件的大小,您最好坚持使用 XmlHttpRequest 并放弃分块传输编码。 或者,您可以尝试使用新的 Fetch API:
https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM