处理 Koa-BODY 错误:’fields’和‘files’属性为空
Koa 是一个优雅的 Node.js 框架,由于其简单、灵活和易于扩展,它越来越受到前端开发者的喜爱。然而,当使用 Koa 中间件 Koa-BODY 处理文件上传时,有时可能会遇到 fields 和 files 属性为空的错误。这篇文章将深入探讨此错误的原因,并提供有效的解决方案。
错误描述
当使用 Koa 接收一个包含文本和文件的 multipart/form-data POST 请求时,如果请求不包含任何文件,则使用 Koa-BODY 中间件处理请求后,fields 和 files 属性会变成空。例如:
----- --- - --------------- ----- ------- - -------------------- ----- --- - --- ------ ----------------- ---------- ----- ---- ------------- ----- -- - ------------------------------ -- -- - ------- --- ------ -- - --- -----------------
如上所示,当请求不包含任何文件时,输出结果会变成:
- ------- --- ------ -- -
原因分析
需要了解以下知识点:
- 浏览器生成的 multipart/form-data 中包含的 boundary 用于分隔不同数据段;
- Koa-BODY 中间件默认的 { multipart: true } 选项启用了文件上传检测;
- Koa-BODY 的文件上传处理是根据表单数据按照 boundary 分割成多段来进行处理的。
当要上传文件时,浏览器会生成一个名为 multipart/form-data 的数据协议,并用一个 boundary 分隔符分隔多个表单项。服务器端的代码会按照这个 boundary 分隔符来解析数据流。当数据中没有文件时,该分割符只被用作一个字符串,因此 Koa-BODY 中间件无法判断是否有文件被上传,所以 fields 和 files 属性为空。
解决方案
方案一:手动处理请求
我们可以不用 Koa-BODY 中间件,而是手动处理请求,在请求中使用 stream 或 pipe 将文件数据写入磁盘,使用 Buffer 类型存储文本数据。以下是示例代码:
----- --- - --------------- ----- ------ - ------------------ ----- --- - --- ------ ------------- ----- -- - -- --------------------------------------- - ----- ----- - --- ----- ------ - --- ----- ------ - --- ---------------- ------------------ ------------------ ------------------- ---- ------------------- ------------- --------- --------- - ----------------- - ---- --- ----------------- ------------------- ----- --------- --------- --------- - ----- ------- - --- --------------- -------------- - ------------------- --- -------------- ---------- - ---------------- - - ----- ----------------------- ----- --------- --------- --------- --------- --------- -- --- --- ------------------- ---------- - ---------------- - - ------ ------ ------- ------ -- --- ------ --------------------- - --------------- --- -----------------
在这个示例代码中,我们使用 Busboy 库手动处理请求。这个库支持流式传输,并处理了边界分隔符。在处理文件时,我们使用 Buffer 存储文件数据,并将其存储在 files 对象中。接着,我们将 files 和 fields 对象存储在 request.body 中。
方案二:删除 Koa-BODY 中间件默认的文件上传检测选项
我们可以通过删除文件上传检测选项来解决这个问题。以下是示例代码:
----- --- - --------------- ----- ------- - -------------------- ----- --- - --- ------ ----------------- ---------- ----- ----------- - --------------- ----- ---------- ----- -- ---------- ----- ------------ ------ ----- -- ------- -- ------ - ---- ------------- ----- -- - ------------------------------ -- -- - ------- --- ------ -- - --- -----------------
在这个示例代码中,我们将 Koa-BODY 的 onFileBegin 配置项设置为判断是否存在 name 或 file,如果这两个属性都不存在,则返回 true。这种方式将禁用 Koa-BODY 中间件的文件上传检测,但不是很安全。
结论
在处理 Koa 中的文件上传时,我们有两种解决方案。方案一手动处理请求,获取 files 和 fields,并存储在 request.body 对象中。方案二是禁用 Koa-BODY 中间件的文件上传检测选项,但这种方式并不是很安全。无论选择哪种方式,我们都应该根据实际需求进行选择。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/670fc7295f5512810267422d