Nodejs:以二进制方式上传文件,并希望在 express 捕获上传进度,如何通过 nginx 中转

下面是一个文件上传的 express demo, 文件以二进制方式上传

import fs from 'node:fs'
import express from 'express'
import stream from 'progress-stream'

const port = 3000 const app = express()

app.post(’/upload’, function (req, res) { const length = req.headers[‘content-length’] const str = stream({ length, time: 100, }) str.on(‘progress’, (process) => { let percent = process.percentage | 0 // 这里可以打印进度 console.log(percent, percent) }) req.pipe(str).pipe(fs.createWriteStream(test.mp4)) req.on(‘end’, async () => { res.status(200).end(‘ok’) }) })

server.listen(port, () => { console.log('server start at ’ + port) })

此时,如果前端直接通过 3000 端口与 express 交互, 流媒体上传的进度可以被正常捕获。

[ 问题 ]:

如果想通过 nginx 服务器转发,应该如何配置呢?

目前简单如下配置,nginx 将在文件完整接收后一次性发送给 express ,也就是说 express 无法捕获上传进度

location / {
    client_max_body_size 100m;
    proxy_pass http://127.0.0.1:3000/;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
}

Nodejs:以二进制方式上传文件,并希望在 express 捕获上传进度,如何通过 nginx 中转

3 回复

把 nginx proxy buffer 关掉?不过这么做的话如果处理速度过慢,上传速度也会受到限制。


谢谢,查了下确实有 proxy_buffering on | off 参数,明天试试看。慢就慢一些,主要是希望通过 nginx 挂证书。目前证书直接挂在 express 下 :(

在Node.js中使用Express处理二进制文件上传并捕获上传进度,同时通过Nginx中转,可以遵循以下步骤:

  1. 前端上传设置:确保前端以二进制方式(如FormData)上传文件。

  2. Express服务器端处理

    • 使用multer中间件处理文件上传。
    • 自定义存储引擎以捕获上传进度。
const express = require('express');
const multer = require('multer');
const path = require('path');

const app = express();
const upload = multer({ dest: 'uploads/' });

// 自定义存储引擎捕获进度
upload.use((req, file, cb) => {
    let progress = 0;
    const busboy = new (require('busboy'))({ headers: req.headers });
    busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
        file.on('data', (chunk) => {
            progress += chunk.length;
            console.log(`Progress: ${(progress / file.size * 100).toFixed(2)}%`);
        });
        file.on('end', () => {
            cb(null, { path: path.join(__dirname, 'uploads', filename), filename: filename });
        });
    });
    req.pipe(busboy);
});

app.post('/upload', upload.single('file'), (req, res) => {
    res.send('File uploaded successfully');
});

app.listen(3000, () => {
    console.log('Server started on port 3000');
});
  1. Nginx配置
    • 配置Nginx作为反向代理,将请求转发到Express服务器。
server {
    listen 80;
    server_name yourdomain.com;

    location /upload {
        proxy_pass http://localhost:3000/upload;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

确保Nginx已正确安装并配置,且能够访问Express服务器。

回到顶部