使用 Deno 和 Oak 处理多部分/表单数据

Mar*_*ers 2 javascript forms upload deno oak

我在学习 Deno 和 Oak 方面取得了缓慢但稳定的进展,但这让我感到困惑。我有一个带有文件上传字段的简单网络表单:

<form method="post" action="/quote" enctype="multipart/form-data">
  <label>Author:
  <input type="text" name="author" />
  </label>
  <label>file: <input type="file" name="myfile" multiple />
  </label>
  <label>Quote: 
  <textarea name="quote"></textarea>
  </label>
  <input type="submit" />
  </form>
Run Code Online (Sandbox Code Playgroud)

处理是通过 Deno 和 Oak 完成的,下面是处理文本数据的脚本:

router.post('/quote', async context => {
const body = context.request.body({ type: 'form' })
  const value = await body.value
  const author = value.get('author')
  console.log(author)
  context.response.redirect(`/?author=${author}`)
})
Run Code Online (Sandbox Code Playgroud)

该路由可以处理没有编码的表单multipart/form-data,但一旦我添加该编码,该author字段就是undefined

我的问题是:如何访问此表单中的数据(文本和文件数据)?

Mar*_*ers 8

该解决方案隐藏在Oak 文档中。Request对象的属性包括Context方法body()。这“解析为请求正文的一个版本”。

它需要一个options实现该接口的对象BodyOptions。它有一个名为 的属性,如果您打算解析,type则该属性的值需要为。form-datamultipart/form-data

在这种情况下,它返回一个实现该FormDataReader接口的对象,其中包括一个解析为包含来自所有表单字段read()(包括上传的任何文件)的数据的对象的方法。

以下是应如何实施的示例:

router.post('/foo', async context => {
    const body = await context.request.body({ type: 'form-data'})
    const data = await body.value.read()
    console.log(data)
    context.response.redirect('/')
})
Run Code Online (Sandbox Code Playgroud)

这是输出的示例。它包括一个包含fields表单字段数据的属性和一个files包含您上传的所有文件数据的数组:

{
  fields: { name: "Foo", organisation: "Bar" },
  files: [
    {
      content: undefined,
      contentType: "image/png",
      name: "myimage",
      filename: "/tmp/c8290ba0/e25ee9648e3e5db57f5ef3eb4cfa06704ce5f29c.png",
      originalName: "foobar.png"
    }
  ]
}
Run Code Online (Sandbox Code Playgroud)

  • 为什么内容未定义?图像数据不应该在那里吗? (2认同)