iOS快捷指令上传文件至Deno服务器超时问题排查
问题:iOS快捷指令上传图片到Deno HTTP服务器超时,Node.js服务器正常
问题描述
我用Deno编写了一个简单的HTTP服务器,尝试通过iOS快捷指令的「获取URL内容」功能上传图片时,服务器明明已经收到带图片的请求并返回了响应,但快捷指令会挂起后报错超时。改用Postman测试或上传JSON数据时一切正常,换成Node.js编写的同逻辑服务器也没有问题。想问问题出在哪里?iOS是否需要特殊响应头?
Deno HTTP服务器代码
import { serve } from "https://deno.land/std@0.178.0/http/server.ts"; serve((_: Request) => { // do something with request // ... return new Response("hello", { status: 200, headers: new Headers({ "content-type": "text/plain", }), }); });
无问题的Node.js服务器代码
const http = require('http'); const hostname = '0.0.0.0'; const port = 8000; const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World'); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
设备信息
10:20:11> lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.1 LTS Release: 22.04 Codename: jammy 10:20:18> uname -r 5.15.0-60-generic 10:20:19> deno --version deno 1.31.0 (release, x86_64-unknown-linux-gnu) v8 11.0.226.13 typescript 4.9.4
问题原因与解决方案
核心问题是Deno的serve默认不会自动消费请求体,而iOS快捷指令上传图片时会发送带请求体的POST请求。Node.js的http模块会自动处理请求体的读取,但Deno遵循Web标准的Request/Response规范,要求开发者显式读取并消费请求体——如果请求体未被读取,TCP连接会一直保持打开状态,导致iOS端触发超时。
修改后的Deno服务器代码如下:
import { serve } from "https://deno.land/std@0.178.0/http/server.ts"; serve(async (req: Request) => { // 必须显式消费请求体,否则连接无法正常关闭 await req.text(); // 若需处理图片,可改用 req.formData() 解析multipart数据 return new Response("hello", { status: 200, headers: new Headers({ "content-type": "text/plain", }), }); });
补充说明
当客户端发送包含请求体的请求时,服务器必须读取完整的请求体,TCP连接才会正常关闭。Node.js的默认处理逻辑帮开发者做了这件事,但Deno需要开发者手动完成。如果需要处理上传的图片,可使用req.formData()解析multipart/form-data格式的请求体,从中提取图片文件数据。
内容的提问来源于stack exchange,提问作者Michael C. Welnick
相关产品推荐
相关产品推荐

