使用multer时出现错误:Multipart: Boundary not found,该请求由POSTMAN发送。

56

注意: 只有当我在Postman中使用form-data body form(这是我必须使用的表单,因为我要发送文本字段之外的文件)时,我才会遇到以下错误:

Error: Multipart: Boundary not found.

当我使用x-www-form-urlencoded时一切正常。(当然,当body-parser用作中间件时

这是请求内容:(由Postman创建)

POST /test HTTP/1.1
Host: localhost:3000
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW
Cache-Control: no-cache
Postman-Token: 61089a44-0b87-0530-ca03-a24374786bd1

------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="test"

a simple word
------WebKitFormBoundary7MA4YWxkTrZu0gW
Content-Disposition: form-data; name="data"

good
------WebKitFormBoundary7MA4YWxkTrZu0gW--

index.js:

var express = require('express');
var app = express();

var multer = require('multer');
var upload = multer();

app.post('/test', upload.array(), function (req, res, next) {
    console.log(req.body.test);
    console.log(req.body);
});

app.listen(3000, function () {
    console.log('app started');
});

如果你在 React Native 中遇到了这个问题,请查看此答案进入链接描述 - Shazil Sattar
8个回答

136
我找到了解决方案。我只需要防止Postman发送Content-Type头信息。所以我只是从请求头中将其删除了。

5
谢谢,它有效了。你能解释一下背后的原因吗? - Hassam Saeed
完美运行! - Gautham Vijayan
我认为这个答案回答了问题。 - Casual _R

11
为了解释为什么会发生这种情况, 在任何HTTP请求中使用内容类型'multipart/form-data'时,可以在'Content-Type'规范旁边添加一个边界信息,如下所示:
Content-Type: multipart/form-data; boundary=MyBoundary

你可以用任何你喜欢的字符串替换MyBoundary

然后,您需要将表单数据(name=Abebe&age=5)进行编码:

--MyBoundary
Content-Disposition: form-data; name="name"

Abebe
--MyBoundary
Content-Disposition: form-data; name="age"

5
--MyBoundary--

更多信息请阅读此StackOverflow问题和答案


9
如果你正在使用Fetch方法
fetch("http://localhost:4000/upload_files", {
    method: 'POST',
    body: formData,
    headers: {
      "Content-Type": "multipart/form-data"
    }
})

设置请求头以便Fetch API自动设置请求头。现在移除请求头或者"Content-Type": "multipart/form-data"。

fetch("http://localhost:4000/upload_files", {
    method: 'POST',
    body: formData
})

现在它可以正常工作。

5

对于 JMeterpostman,请从 header 中移除 Content-Type

这样可以解决您的问题。


3
我将稍微解释一下对于那些在前端遇到相同问题并想知道如何删除标题的人的 user9150719 。
我也遇到了同样的问题;我试图从 Angular 应用程序向我的 Node.js 服务器发帖。我的 post 请求包括原始数据和一个文件输入。因此,我考虑使用 FormData()Angular 服务
//Declare header variables. 

formDataHeader = {
        headers: new HttpHeaders({
          Accept: 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Content-Type': 'multipart/form-data',
          Authorization: 'Bearer ' + this._myService.getToken()
        })
      };

//Post function to Nodejs server
    addNewContact(contact: FormData): any {

        return this._httpClient.post(
          environment.apiBaseUrl + '/contacts', // POST /api/contacts
          (contact), // contact data,
          this.formDataHeader
        );
    }

我的formData已经正确设置。我能够获得所有数据,但问题是我在请求中设置了几个标头导致用户9150719遇到的问题。

我的解决方案是将我的标头简化为以下内容:

formDataHeader = {
        headers: new HttpHeaders({
          Authorization: 'Bearer ' + this._myService.getToken()
        })
      };

重要的一点是,我不需要在我的<form></form>标签上设置enctype="multipart/form-data"
即使我设置了一个httpInterceptor(我认为它没有正常工作),我仍然需要在所有请求中添加Authorization头部,但所有其他headers都会导致我的api调用返回意外结果。
最后,我认为(但我并不完全确定)我不需要设置额外的头部的原因是,在我的NodeJS服务器上,我已经配置了预期的头部。 Node.JS服务器
// app.js

app.use('/public/uploads', express.static('uploads'));
app.use('/public', express.static('public'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(cors());
app.use((req, res, next) => {
    res.header('Access-Control-Allow-Origin', '*');
    res.header('Access-Control-Allow-Headers', 'x-www-form-urlencoded, Origin, X-Requested-With, Content-Type, Accept, Authorization, *');
    if (req.method === 'OPTIONS'){
        res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, PATCH, DELETE, OPTIONS');
        res.setHeader('Access-Control-Allow-Credentials', true);
        return res.status(200).json({});
    }
    next();
});
app.use(bodyParser.urlencoded({limit: '50mb', extended: true}));
app.use(bodyParser.json({limit: '50mb', extended: true}));

我认为,如果您的服务器已经设置好处理某些类型的头信息(如Content-Type、Authorization、Origin等),当您向服务器发送请求时,不一定需要在前端再次设置这些头信息。但也有一些例外,比如Authorization在某些情况下需要设置,可能是因为它们携带了token或其他相关数据。

希望这能帮助到某个人!


1

在使用axios/fetch或任何第三方HTTP处理程序上传文件时,请勿提及CONTENT-TYPE头。

原因是我们不知道文件的边界。如果您仅传递“multipart/form-data”作为Content-Type,则会出现错误,因为我们没有在其中传递边界。

因此,让浏览器根据附加的文件添加它(multipart/form-data)以及基于边界的内容。

如果您想要发送一些数据和文件,请将它们作为multipart/form-data发送(同样,我们不需要手动添加此标题)。

我们不能同时为任何http调用发送多个Content-Type数据。 请参考下面的代码。

async onUpload(){
  const formData=new FormData();
  formData.append('files', file1);
  formData.append('files', file2);
  formData.append('data', {key1:value1, key2:value2});
  const res=await axios.post(URL, formData);
}

知会 @hassam-saeed


如果是从React Native移动应用程序调用的话,是否也不需要传递头部信息? - undefined

0

0

如果有人遇到和我一样的问题。

NestJs - 后端

NextJs - 前端

我试图做类似于:

const formData = new FormData()

formData.append('context', body.context.toString())
    
body.files.map((file) => {
    formData.append('files', file, `${file.name}`)
})

const response = await fetch(url, {
    method: 'POST',
    headers: {
        'Content-Type': 'multipart/form-data',
        ...(access_token ? { Authorization: `Bearer ${access_token}` } : {}),
    },
    body: formData,
})

但是由于这个“Content-Type”覆盖了浏览器的“Content-Type”设置,并且内容长度没有明确设置(我认为这才是真正的问题),表单数据仍然以编码形式显示在后端。因此,NestJS无法解析“context”变量或“files”。
另外,如果您在NextJS中使用api路由,请记住检查是否有任何地方覆盖了“Content-Type”... 我也遇到了这个问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接