【发布时间】:2021-09-10 20:28:47
【问题描述】:
我知道我可以在客户端创建一个 FormData 并将其发送到服务器(在本例中我使用的是 Deno/Oak),然后从那里读取它。
但是反之亦然吗?
如果我在 Oak 中有一条路由,并且我希望它发送多部分响应(带有一个或多个 blob,以及一个或多个字符串),我该怎么做?
【问题讨论】:
标签: response multipart form-data deno oak
我知道我可以在客户端创建一个 FormData 并将其发送到服务器(在本例中我使用的是 Deno/Oak),然后从那里读取它。
但是反之亦然吗?
如果我在 Oak 中有一条路由,并且我希望它发送多部分响应(带有一个或多个 blob,以及一个或多个字符串),我该怎么做?
【问题讨论】:
标签: response multipart form-data deno oak
Oak 的automatic response body handling 支持FormData,因此您可以将context.response.body 设置为FormData 的实例,然后Oak 会处理其余的事情。例如:
import { Application } from "https://deno.land/x/oak@v9.0.0/mod.ts";
const app = new Application();
app.use((ctx) => {
const data = new FormData();
data.append("string1", "Hi");
data.append("string2", "Bye");
data.append("blob1", new Blob(['<a id="a">Hi</a>'], { type: "text/xml" }));
data.append("blob2", new Blob(['<b id="b">Bye</b>'], { type: "text/xml" }));
ctx.response.body = data;
});
await app.listen({ port: 8000 });
% curl localhost:8000
------7115155097707325061106360125
Content-Disposition: form-data; name="string1"
Hi
------7115155097707325061106360125
Content-Disposition: form-data; name="string2"
Bye
------7115155097707325061106360125
Content-Disposition: form-data; name="blob1"; filename="blob"
Content-Type: text/xml
<a id="a">Hi</a>
------7115155097707325061106360125
Content-Disposition: form-data; name="blob2"; filename="blob"
Content-Type: text/xml
<b id="b">Bye</b>
------7115155097707325061106360125--
同样可以直接在 Deno 中完成,无需任何额外的框架:
const server = Deno.listen({ port: 8000 });
for await (const conn of server) serveHttp(conn);
async function serveHttp(conn: Deno.Conn) {
const httpConn = Deno.serveHttp(conn);
for await (const requestEvent of httpConn) {
const data = new FormData();
data.append("string1", "Hi");
data.append("string2", "Bye");
data.append("blob1", new Blob(['<a id="a">Hi</a>'], { type: "text/xml" }));
data.append("blob2", new Blob(['<b id="b">Bye</b>'], { type: "text/xml" }));
requestEvent.respondWith(new Response(data));
}
}
【讨论】:
context.response.headers.set("Content-Type", "multipart/form-data") 设置在正文的 Oak 响应之前,并在客户端获取中添加/删除 headers: {"Content-Type": "multipart/form-data"},但没有运气。
curl 和 Chromium 浏览器对我来说很好,但在 Insomnia 中却不行……有趣的是,我之前在我的答案中添加的本机 Deno 解决方案在 Insomnia 中有效。响应标头也不同; Deno.requestEvent'` resondWith 导致 Content-Type 在其中包含一个“边界”(例如 multipart/form-data; boundary=----7830127428108890346214010889),而 Oak 解决方案没有。这可能是 Oak 中的一个错误。我不肯定。我自己没怎么用过Oak。它只发送`multipart/form-data`...
.then(response => response.formData()),但它说:“无法将内容解析为 FormData。”,可能是因为缺少边界。无论如何,我已经订阅了 Oak 中的问题,我会坚持下去。