最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Handling multipartform-data with Deno and Oak - Stack Overflow

programmeradmin2浏览0评论

I'm making slow but steady progress in learning Deno and Oak but this has me stumped. I have a simple web form with a file upload field:

<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>

The processing is done with Deno and Oak and here is the script that handles the text data:

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}`)
})

The route can handle a form which does not have an encoding of multipart/form-data but as soon as I add that, the author field is undefined.

My question is: how can I access the data from this form (both the text and file data)?

I'm making slow but steady progress in learning Deno and Oak but this has me stumped. I have a simple web form with a file upload field:

<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>

The processing is done with Deno and Oak and here is the script that handles the text data:

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}`)
})

The route can handle a form which does not have an encoding of multipart/form-data but as soon as I add that, the author field is undefined.

My question is: how can I access the data from this form (both the text and file data)?

Share Improve this question asked Dec 29, 2020 at 18:07 Mark TyersMark Tyers 3,2894 gold badges35 silver badges58 bronze badges 1
  • Is there any way to handle file uploads in Oak? I've seen a couple of tutorials but they all use broken libraries. – Mark Tyers Commented Jan 5, 2021 at 20:56
Add a ment  | 

3 Answers 3

Reset to default 9

The solution is buried in the Oak documentation. The Request property of the Context object includes a body() method. This "resolves to a version of the request body".

It takes an options object that implements the BodyOptions interface. It has a single property called type which needs to have a value of form-data if you intend parsing multipart/form-data.

In this scenario it returns an object that implements the FormDataReader interface and this includes a read() method that resolves to an object containing the data from all the form fields, including any files uploaded.

Here is an example of how it should be implemented:

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('/')
})

And here is an example of the output. It includes a fields property which contains the data from the form fields and a files array which contains the data for all the files you uploaded:

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

Here's an update for Oak 16+, and how to save the file on the server. The syntax seems to have changed quite a bit for some things.

I have routing set up with

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

import handlers from "./requestHandlers.ts";

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

And then in my request handlers (I have UPLOAD_PATH defined as a constant elsewhere):

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}`;
  }
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}`)
})
发布评论

评论列表(0)

  1. 暂无评论