node 中间层转发文件上传是否必须将文件存在本地呢

2019-01-24 11:50:12 +08:00
 az09py

先通过 formidable 解析文件,会把文件存到本地 然后通过 request.post 上传文件,这里必须文件必须通过 form.append (‘ file ’,fs.createReadStream(file.path))进行处理 这样就会在服务器上创建文件

4872 次点击
所在节点    Node.js
11 条回复
libook
2019-01-24 14:10:06 +08:00
不需要吧,用 Stream,先建立客户端发来的请求的读 Stream,然后再建立转发到目标服务的写 Stream,然后两边管道接在一起。
hcymk2
2019-01-24 14:11:43 +08:00
pipe。
doublleft
2019-01-24 14:55:25 +08:00
不用,可以 form.buffer
az09py
2019-01-24 15:54:28 +08:00
@libook 直接不需要 formidable 解析成 File 了么
az09py
2019-01-24 15:56:12 +08:00
@hcymk2 可以大致讲讲思路吗
libook
2019-01-24 16:30:12 +08:00
看你想做哪些事情了,如果什么事情都不做,直接把上游发来的文件传递给下游,可以直接把 Stream 传递过去。

```
http.createServer(function(req, res) {
//这里的 req 是个 Stream
const options = {
hostname: 'http://你的上传服务器地址',
port: 80,
path: '/upload',
method: 'POST',
headers: {
//这里写一些必要的头
}
};

/**
* 这个 uploadReq 也是个 Stream
*/
const uploadReq = http.request(options, (res) => {
//这里处理上传服务器的 response
});

req.pipe(uploadReq);//关键点,把上游发来的 Stream 直接管道接到下游上传服务器的 Stream 上


}).listen(8080);
```

上面是个示范,不是一个可执行的代码,只是提供一个思路。
lps
2019-01-25 14:23:35 +08:00
可以参考 eggjs 的文件上传,不需要保存临时文件,直接通过 stream 转发到 OSS 存储
dtlqwjj
2019-02-15 18:20:13 +08:00
@doublleft file.buffer,怎么添加到 formdata,是 xx.append('file', file.buffer)吗?
chogath
2020-09-01 16:40:50 +08:00
node 中间层转发文件上传 可以使用 代理模式

import { createProxyServer } from 'http-proxy';

const proxy = createProxyServer({});

const target = '< 需要转发的 url >'

const result = await new Promise((resolve, rej) => {
proxy.web(
req,
res,
{ target, ignorePath: true },
(err: Error) => { if (err) rej(err.message); },
);
});
keji
2021-08-27 09:01:44 +08:00
目前已解决,分享下我的方案,完整代码如下:

const express = require("express");
const multer = require("multer");
const upload = multer();
const app = express();
app.post("/photos/upload", upload.array("files"), function (req, res, next) {
//这里我默认取了数组的第一个数据,大家根据实际的情况进行组合数据
const { originalname, mimetype, buffer } = req.files[0];
request.post(
{
url: "后端服务器地址",
headers: {
//这里写一些必要的头
},
formData: {
//注意,这里一定要按这样的格式写,因为如果不这样写的话
//其中的 filename 字段会丢失 /Content-Type 的类型跟实际传过来不一致的,所以最好自己提前设置好
//比如正确的是这样的(下面两行)
//Content-Disposition: form-data; name="file"; filename="xxx"
//Content-Type: image/jpeg
//这个 bug 困扰我好久了,最后是通过抓包工具分析出来的(太菜了)
file: {
value: buffer,
options: {
filename: originalname,
contentType: mimetype,
},
},
},
},
(error, res, body) => {
// console.log(res)
}
);
});

参考资料:
https://github.com/expressjs/multer
https://www.npmjs.com/package/request
fengfuliu
2022-10-22 13:30:19 +08:00
@keji 非常感谢老哥 在我折腾一天后,你的回答帮我解决了问题

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/530158

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX