如何在 Node 中使用 http2 模块发布包含文件字段的表单数据?

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

我创建了一个

FormData
,如下(简化):

import FormData from 'form-data';

const createForm = async () => {
  const form = new FormData();
  form.append('field1', 'stringValue1');

  form.append('fileField', fs.createReadStream(__filename), {
    contentType: 'text/javascript',
    filename: 'file.js',
  });

  return form;
};

然后通过 HTTP/2(明文)发送:

  // app is a FastifyInstance
  await app.ready();
  const { address, port } = app.server.address();
  const client = http2.connect(`http://${address}:${port}`);
  const request = client.request({
    ':method': 'POST',
    ':path': '/path',
    'content-type': `multipart/form-data; boundary=${form.getBoundary()}`,
  });
  request.setEncoding('utf8');

  let status;
  request.on('response', (headers) => {
    status = headers[':status'];
  });
  request.on('data', (data) => { ... });

  form.pipe(request);
  request.end();

  await new Promise((resolve) => {
    request.on('end', () => {
      client.close();
      resolve();
    });
  });

然后在 Fastify 服务器中监听我的请求

import fastify from 'fastify';
import fastifyFormbody from '@fastify/formbody';
import fastifyMultipart from '@fastify/multipart';

const app = fastify({ http2: true, logger: logLevel === 'debug' });
const fieldSizeLimit = 1024 * 1024 * 10;

void app.register(fastifyFormbody);
void app.register(fastifyMultipart, {
  attachFieldsToBody: 'keyValues',
  limits: {
    fieldSize: fieldSizeLimit,
    fileSize: fieldSizeLimit,
  },
  onFile: async (part) => {
    const destinationPath = path.join(bundlePath, 'uploads', part.filename);
    await saveMultipartFile(part, destinationPath);
    // eslint-disable-next-line no-param-reassign
    part.value = {
      filename: part.filename,
      savedFilePath: destinationPath,
      type: 'asset',
    };
  },
});

app.post('/path', async (req, res) => {
  console.log(Object.entries(req.body));
  ...
});

它可以很好地处理 HTTP/1.1 请求。并且日志显示未收到

fileField
。如何正确提出请求?

我发现打开http/2连接并发布表单数据,上面写着

在 Node HTTP2 文档中,它展示了如何执行此操作的示例。

但似乎只是在谈论分离

const client = http2.connect(...)
client.request
,而不是表单数据示例。

我需要支持的最低 Node 版本是 20,如果需要的话我很乐意从

form-data
切换;我只是在内置
FormData
时遇到了不同的错误,但也许我在那里做错了什么。

node.js http2 fastify-multipart
1个回答
0
投票

解决办法是更换

  form.pipe(request);
  request.end();

  form.pipe(request);
  form.on('end', () => { request.end(); });
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.