KrakenD:使用 Form-Data 通过 POST 请求通过网关上传文件时遇到问题
描述您想要做什么
在我的一个应用程序中,我需要从我的角度网站将文件上传到我的服务器。 基本上,为此,我使用 FormData 对象来附加一些信息,例如文件名等。 为了发送文件本身,我将在 FormData 中附加一个 fs.readStream()。 然后我通过 axios 将其发布到我的服务器端点。
代码示例(使用表单数据的邮递员请求):
var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
data.append('avatar', fs.createReadStream('/home/file.mp3'));
data.append('title', 'test');
data.append('description', 'test');
var config = {
method: 'post',
url: 'localhost:8080/upload-file',
headers: {
...data.getHeaders()
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
关于服务器,它是在node.js中开发的,我使用“multer”中间件来检索文件。
端点代码示例:
import {Response, Request} from "express";
public static async UploadFile(req: Request, res: Response): Promise<any> { }
没有 krakend 网关,它可以完美工作,然后我可以检索端点中的文件,以便: req.file 其他发送的信息如“标题”,“描述”都在req.body中
使用krakend,我得到了服务器端除文件之外的所有信息,在请求中,我只找到了req.body而不是req.file
所以我的问题是,为什么 krakend 不将文件数据发送到后端,以及通过 POST 请求 FormData 将文件发送到 krakend 的解决方案是什么?
您的配置文件 krakend.json
的内容:
{
"version": 3,
...
{
"endpoint": "/upload",
"method": "POST",
"output_encoding": "no-op",
"backend": [
{
"method": "POST",
"encoding": "no-op",
"url_pattern": "/upload-file",
"host": [
"http://containername:8080"
]
}
]
}
}
我尝试使用不同的“no-op”注释,但没有任何作用,我的印象是 krakend 无法解释我的文件上传
使用的命令 您是如何启动该软件的?
I use docker-compose:
krakend:
container_name: 'Gateway'
image: devopsfaith/krakend
volumes:
- ./KrakenD/dev/:/etc/krakend
ports:
- "8080:8080"
- "1234:1234"
- "8090:8090"
links:
- some containers
- ...
restart: always
network_mode: bridge
日志 我没有特定的日志,只有我的后端返回 400 代码,因为它找不到请求中的文件信息。
Describe what are you trying to do
In one of my applications, I need to upload a file to my server from my angular website.
Basically, to do this I use the FormData object to which append several informations, like the file name, and others.
To send the file itself I will append to the FormData an fs.readStream().
Then I post this via axios to my server endpoint.
Exemple of code (postman request using form-data):
var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
data.append('avatar', fs.createReadStream('/home/file.mp3'));
data.append('title', 'test');
data.append('description', 'test');
var config = {
method: 'post',
url: 'localhost:8080/upload-file',
headers: {
...data.getHeaders()
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
Concerning the server, it is developed in node.js and I use the "multer" middleware to retrieve the file.
Exemple of an endpoint code :
import {Response, Request} from "express";
public static async UploadFile(req: Request, res: Response): Promise<any> { }
Without krakend gateway, it's works perfectly and I can then retrieve the file in my endpoint so that: req.file
The others informations sent like "title", "description" are in req.body
Using krakend, I get all the information on the server side except the file, in the request, I only find the req.body and not the req.file
So my question is, how come krakend is not sending the file data to the backend and what would be the solution in order to send file via POST request a FormData to krakend ?
Your configuration file
The content of your krakend.json
:
{
"version": 3,
...
{
"endpoint": "/upload",
"method": "POST",
"output_encoding": "no-op",
"backend": [
{
"method": "POST",
"encoding": "no-op",
"url_pattern": "/upload-file",
"host": [
"http://containername:8080"
]
}
]
}
}
I tried to use the different "no-op" annotations but nothing works, I have the impression that krakend does not interpret my file upload
Commands used
How did you start the software?
I use docker-compose:
krakend:
container_name: 'Gateway'
image: devopsfaith/krakend
volumes:
- ./KrakenD/dev/:/etc/krakend
ports:
- "8080:8080"
- "1234:1234"
- "8090:8090"
links:
- some containers
- ...
restart: always
network_mode: bridge
Logs
I don't have a specific log, only my backend which returns a 400 code as it can't find the file information in the request.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对于那些正在经历同样问题的人。请注意,邮递员是造成我问题的原因,KrakenD 确实支持将正文作为多部分/表单数据发送,因此不要忘记根据需要让标头通过。
问题是,当通过邮递员时,我无法解释,但文件发送到 krakenD 的情况很糟糕。使用 Insomnia 或简单的 Curl 进行测试。
for those who are going through the same problem. Please note that postman was the cause of the problem for me, KrakenD does support sending bodies as multipart/form-data, so don't forget to let the headers through as needed.
The problem is that when passing through postman, I can't explain but the file is badly sent to krakenD. Use Insomnia, or a simple Curl to do your tests.
也许您必须在输入标题中包含“Content-Type”。
在这里您可以找到有关它的更多信息。
Maybe you have to include "Content-Type" at input-headers.
Here you can find more info about it.
我遇到了同样的问题,我解决了它,包括标题中的“Content-Type”。我在端点中使用一些模板来进行一些额外的配置。
我在端点中仅包含“AuthValidator”,然后手动包含我的 input_headers,如下所示:
当您使用模板时,模板会覆盖同一级别中的某些参数,因此我必须将 MyConfig 分成 2 个级别以允许自定义配置来自模板。
I had the same problem, I solved it incluind "Content-Type" in headers. I'm using some template in my endpoints to some extra configs.
I include only "AuthValidator" in my endpoint and then include my input_headers manually, like this:
When you use a template, the template overwrite some param in the same level, so I've to split MyConfig in 2 levels to allow a custom config from a template.