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

问题描述 投票:0回答:3

我在学习 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>

处理是通过 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}`)
})

该路由可以处理一个表单,该表单not具有

multipart/form-data
的编码,但一旦我添加它,
author
字段就是
undefined

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

javascript forms upload deno oak
3个回答
8
投票

解决方案隐藏在Oak 文档中。

Request
对象的
Context
属性包含
body()
方法。这“解析为请求正文的一个版本”。

它需要一个实现

options
接口的
BodyOptions
对象。它有一个名为
type
的属性,如果您打算解析
form-data
,则需要具有
multipart/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('/')
})

这是输出的示例。它包括一个

fields
属性,其中包含表单字段的数据和一个
files
数组,其中包含您上传的所有文件的数据:

{
  fields: { name: "Foo", organisation: "Bar" },
  files: [
    {
      content: undefined,
      contentType: "image/png",
      name: "myimage",
      filename: "/tmp/c8290ba0/e25ee9648e3e5db57f5ef3eb4cfa06704ce5f29c.png",
      originalName: "foobar.png"
    }
  ]
}

0
投票

这是 Oak 16+ 的更新。对于某些事情,语法似乎发生了很大变化。

我已经设置了路由

import { Router } from "jsr:@oak/oak@16";
const router = new Router();

import handlers from "./requestHandlers.ts";

router
  .post("/upload", handlers.handleUpload);

然后在我的请求处理程序中(我在其他地方将 UPLOAD_PATH 定义为常量):

handleUpload: async  ({ request, response }: { request: any; response: any }) => {
    const theBody: Body = await request.body;
    const form: FormData = await theBody.formData()
    const theFile: File = form.get("file") as File;
    const destPath = `${config.UPLOAD_PATH}${theFile.name}`;
    const fileData = await theFile.stream()
    Deno.writeFile(destPath, fileData);

    response.body = `Uploaded file size: ${theFile.size}`;
  }

-2
投票
router.post('/quote', async context => {        
    let params: {[key: string]: string} = {};
    let value: any = await context.request.body().value;
    for (const [key, valor] of value) {
        params[key] = valor; 
    }
    const author = params['author']
    console.log(author)
    context.response.redirect(`/?author=${author}`)
})
© www.soinside.com 2019 - 2024. All rights reserved.