快递(使用 multer)错误:多部分:找不到边界,请求由 POSTMAN 发送



注意:只有当我在Postman中使用表单数据正文表单时(这是我必须使用的表单,因为我想在文本字段旁边发送文件),我得到:

Error: Multipart: Boundary not found.

当我使用x-www-form-urlencode时,一切都很好。(当然,当身体解析器用作中间件时)

这是请求内容:(由邮递员制作)

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--

索引.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');
});

我找到了解决方案。我只需要阻止邮递员发送Content-Type标头。所以我只是从请求标头中删除了它。

为了深入了解为什么会发生这种情况,

在任何 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--

有关更多信息,请阅读此堆栈溢出问题和答案

如果您使用的是 fetch 方法

fetch("http://localhost:4000/upload_files", {
method: 'POST',
body: formData,
headers: {
"Content-Type": "multipart/form-data"
}
})

标头,以便 Fetch api 自动设置标头。现在删除标题或"内容类型":"多部分/表单数据">

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

现在它工作了

对于JMeter邮递员,请从标头中删除Content-Type

它将解决您的问题。

对于那些在前端遇到相同问题并想知道在哪里删除标头的人,我将在 user9150719 上进行一些扩展。

我有同样的问题;我试图从Angular应用程序发布到我的Nodejs服务器。我的 POST 请求包括原始数据和文件输入。所以我在想FormData()

角度服务

//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
);
}

我的表单数据已正确设置。我能够获取所有数据,但问题是我在请求中设置了几个标头,导致 user9150719 遇到什么。

我的解决方案是将我的标头简化为:

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

要指出的另一件重要事情是,我不需要在<form></form>标签上设置enctype="multipart/form-data"

即使我有一个httpInterceptor设置(我认为它无法正常工作),我仍然需要在我的所有请求中添加Authorization标头,但所有其他headers都导致我的 api 调用返回意外结果。

最后,我认为(但我不完全确定)我不需要设置额外标头的原因是因为在我的 NodeJS 服务器中,我已经配置了预期的标头。

节点.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}));

所以我认为,如果您的服务器设置为处理某些类型的标头(内容类型、授权、来源等),则在向服务器发送请求时,您不一定需要在前端再次设置这些标头。有一些例外,例如在某些情况下需要设置Authorization;可能是因为它们以token或这方面的某种形式携带一些数据。

我希望这对那里的人有所帮助!

在使用 axios/fetch 或任何第 3 个 HTTP 处理程序从 FE 上传文件时,不要提及 CONTENT-TYPE 标头。

原因是因为我们不知道文件的边界。如果您仅将"多部分/表单数据"作为内容类型传递,则会收到错误,因为我们没有在其中传递边界。

因此,让浏览器根据附加的文件添加它(多部分/表单数据)以及边界。

如果你想发送一些数据与文件一起,你应该将它们作为多部分/表单数据(同样,我们不需要手动添加这个标头)类型发送.
我们不能一次为任何http调用发送多个内容类型数据。 请参考下面的代码。

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赛义德

如果有人有同样的问题,我就有。

NestJs - 后端

下一页 Js - 前端

我试图做这样的事情:

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,
})

但是由于此"内容类型"覆盖了浏览器的"内容类型"设置,并且未明确设置内容长度(我认为这是真正的问题),因此表单数据显示在后端仍然编码。因此,NestJS无法解析"上下文"变量或"文件"。

另外,如果您在NextJS中使用api路由,请记住检查其中没有任何地方被覆盖"内容类型"。我也有这个问题。

我这样做了

const form = new FormData();
headers['Content-Type'] = `multipart/form-data; boundary=${form._boundary}`;

来源: https://stackoverflow.com/a/54796556/8590519

最新更新