原生 Node.js 如何接受处理 FormData 中的数据

317 阅读1分钟

原生 Node.js 如何接受处理 FormData 中的数据还是比较麻烦的. 首先实现node.js服务端代码如下:

const http = require('http');

const server = http.createServer((req, res) => {
  if (
    req.method === 'POST' &&
    req.headers['content-type'].includes('multipart/form-data')
  ) {
    let body = '';

    req.on('data', chunk => {
      body += chunk.toString(); // 将数据块拼接成完整的请求体
    });

    req.on('end', () => {
      // 此时 body 是原始的 multipart/form-data 数据
      console.log('Raw body:', body);

      // 手动解析 multipart/form-data 数据
      // 这里只是一个简单的示例,实际解析需要处理复杂的边界和编码
      const boundary = req.headers['content-type'].split('boundary=')[1];
      const parts = body.split(`--${boundary}`);

      parts.forEach(part => {
        if (part.includes('Content-Disposition')) {
          const match = part.match(/name="([^"]+)"/);
          if (match) {
            const fieldName = match[1];
            const value = part.split('\r\n\r\n')[1].trim();
            console.log(`Field: ${fieldName}, Value: ${value}`);
          }
        }
      });

      res.end(JSON.stringify({ data: 'FormData received' }));
    });
  } else {
    res.end(JSON.stringify({ data: 'Unsupported request' }));
  }
});

server.listen(3000, () => {
  console.log('Server is running on port 3000');
});

客户端可以在http://localhost:3000/页面里执行如下代码:

// 创建一个 FormData 对象
const formData = new FormData();

// 向 FormData 中添加键值对
formData.append('username', 'JohnDoe');
formData.append('email', 'johndoe@example.com');
formData.append('uid', 'johndoe@example.com');

// 使用 fetch 发送请求
fetch('http://localhost:3000/', {
  method: 'POST',
  body: formData,
})
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json();
  })
  .then(data => {
    console.log('Success:', data);
  })
  .catch(error => {
    console.error('Error:', error);
  });

可以看出body数据要通过事件才可以取到, header里只是告诉了上传的数据格式和数据隔离标记, 需要自行字符串处理, 这还仅是简单的表单实体. 非常麻烦. 不过好在有如 multer 或 formidable 等中间件可以解决这些功能.