Firebase Cloud Functions 和 Busboy 不解析字段或文件

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

我一直在使用 Firebase Cloud Functions 和 Express 进行一些实验,当我尝试使用 Busboy 处理 FormData 时遇到了问题。 我似乎只得到一个大的格式错误的文本字段,其中包含所有数据,还包括我尝试上传的文件的任何二进制数据(即乱码的 ascii 字符)

我尝试了在网上找到的不同解决方案,甚至在SO上,我发现它们都是围绕Google提供的有关多部分数据的示例构建的: https://cloud.google.com/functions/docs/writing/http

这是我的服务器端代码:

// index.js
const functions = require('firebase-functions');
const express = require('express');
const Busboy = require('busboy');

app = express();

app.post('/upload', (req, res) => {
  const busboy = new Busboy({
    headers: req.headers,
    limits: {
      // Cloud functions impose this restriction anyway
      fileSize: 10 * 1024 * 1024,
    }
  });

  busboy.on('field', (key, value) => {
    console.log(`Busboy field ${key}: ${value}`);
  });

  busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
    console.log(`Busboy file ${fieldname}: ${filename}`);
  });

  busboy.on('finish', () => {
    console.log('Busboy finish');
    return res.send({
      status: 'Success',
      text: 'Great job!'
    });  
  });

  busboy.end(req.rawBody);
});

exports.api = functions.https.onRequest(app);

这是 Node JS 中的客户端:

// index.js
import axios from 'axios';
import FormData from 'form-data';

const ENDPOINT_URL = XXXXXXXXXXXXXXXXX;

const postFile = async () => {

    try {
        const form_data = new FormData();
        form_data.append('userName', 'Fred');
        form_data.append('password', 'Flintstone');
        const response = await axios.post(`${ENDPOINT_URL}/upload`, form_data);
        console.log(response.data);
    } catch (error) {
        console.error(`Error: ${error}`);
    }
}

postFile();

在客户端日志上,一切都按预期进行,我得到了“干得好”的回复。但是,这是我在 Firebase Cloud Functions 日志中得到的信息:

Busboy field ----------------------------047691570534364316647196
Content-Disposition: form-data; name: "userName"

Fred
----------------------------047691570534364316647196
Content-Disposition: form-data; name="password"

Flintstone
----------------------------047691570534364316647196--
)

请注意,这只是日志中的单个输出行,这意味着 Busboy 仅调用了一次 onField 。如上所述,如果我向 FormData 添加一个文件,输出会非常混乱,而且我仍然只得到一次对 onField 的调用,而没有对 onFile 的调用。

firebase express google-cloud-functions axios busboy
2个回答
2
投票

经过进一步调查,我发现服务器工作正常,而在客户端我需要更改这一行:

const response = await axios.post(`${ENDPOINT_URL}/upload`, form_data);

至:

const config = { headers: { 'content-type': `multipart/form-data; boundary=${form_data._boundary}` }};
const response = await axios.post(`${ENDPOINT_URL}/upload`, form_data, config);

显然,尽管在其他帖子中有所说明,但不指定多部分标头并不会导致它被自动确定。 另请注意,如果省略

boundary
设置,您将从服务器上的 Busboy 收到
Boundary not found
错误。


0
投票

对我来说,我必须在

bb.end(req.body)
之前写
req.pipe(bb)

© www.soinside.com 2019 - 2024. All rights reserved.