Handling multipart/form-data POST with Express in Cloud Functions

牧云@^-^@ 提交于 2019-12-29 08:42:57

问题


I've been trying to handle POSTs (multipart/form-data) with a Firebase function and Express but it just doesn't work. Tried this in local server and it works just fine. Everything's the same except it's not contained in a Firebase function.

Besides screwing up the request object it seems it also screws up the way busboy works.

I've tried different solutions presented here but they just don't work. As one user mentions, the callbacks passed to busboy (to be called when a 'field' is found or when it finishes going through the data) are never called and the function just hangs.

Any ideas?

Here's my function's code for reference:

const functions = require('firebase-functions');
const express = require('express');
const getRawBody = require('raw-body');
const contentType = require('content-type')
const Busboy = require('busboy');

const app = express();

const logging = (req, res, next) => {
  console.log(`> request body: ${req.body}`);
  next();
}

const toRawBody = (req, res, next) => {
  const options = {
      length: req.headers['content-length'],
      limit: '1mb',
      encoding: contentType.parse(req).parameters.charset
  };
  getRawBody(req, options)
      .then(rawBody => {
          req.rawBody = rawBody
          next();
      })
      .catch(error => {
          return next(error);
      });
};

const handlePostWithBusboy = (req, res) => {
  const busboy = new Busboy({ headers: req.headers });
  const formData = {};

  busboy.on('field', (fieldname, value) => {
      formData[fieldname] = value;
  });

  busboy.on('finish', () => {
      console.log(`> form data: ${JSON.stringify(formData)}`);
      res.status(200).send(formData);
  });

  busboy.end(req.rawBody);
}

app.post('/', logging, toRawBody, handlePostWithBusboy);

const exchange = functions.https.onRequest((req, res) => {
  if (!req.path) {
    req.url = `/${req.url}`
  }
  return app(req, res)
})
module.exports = {
  exchange
}

回答1:


Please read the documentation for handling multipart form uploads.

... if you want your Cloud Function to process multipart/form-data, you can use the rawBody property of the request.

Because of the way Cloud Functions pre-processes some requests, you can expect that some Express middleware will not work, and that's what you're running into.




回答2:


The documentation Doug referred to in his answer is good. An important caveat though is that rawBody does not work in the emulator. The workaround is to do:

if (req.rawBody) {
    busboy.end(req.rawBody);
}
else {
    req.pipe(busboy);
}

As described in this issue: https://github.com/GoogleCloudPlatform/cloud-functions-emulator/issues/161#issuecomment-376563784



来源:https://stackoverflow.com/questions/48289824/handling-multipart-form-data-post-with-express-in-cloud-functions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!