如何实现上传文件到 nodejs 和文件下载

简介: 最近拿 next.js 做个全栈项目,需要文件上传和下载,这里记录下实现方式,也写一下使用原生 node 代码如何实现。

最近拿 next.js 做个全栈项目,需要文件上传和下载,这里记录下实现方式,也写一下使用原生 node 代码如何实现。

文件上传

要实现文件上传,首先需要在页面中拿到文件,demo 里我们简单的写一下:

<input type="file" id="file" />
复制代码
document.querySelector('#file').addEventListener('change', e => {
    if (e.target.files?.[0]) doUpload(e.target.files[0]);
});
复制代码

为了简化一下我们这里例子中使用单文件上传。再来实现下 doUpload,上传文件我们需要使用到 FormData

const doUpload = async file => {
    const body = new FormData();
    body.append('file', file);
    const response = await fetch('/api/file', {
        method: 'POST',
        body
    });
};
复制代码

我们需要先实例化一个 FormData,然后使用 append 将文件作为 form 字段添加进去,然后可以直接通过 fetch 发送 formDatanode 端,当然也可以使用 axios 等库或 xhr 来实现。

axios.post('/api/file', formData, {
    headers: {
        'Content-Type': 'multipart/form-data'
    }
});
复制代码

需要注意在使用 xhr 时要主动配置下请求头中的 Content-Type

这样在选择文件后就会将文件 post 发送到 node/api/file 中,然后我们再在做下 node 端处理下发送过来的请求:

import formidable from 'formidable';
import fs from 'fs';
export const config = {
    api: {
        bodyParser: false
    }
};
const saveFile = async file => {
    const data = fs.readFileSync(file.path);
    fs.writeFileSync(`./public/${file.name}`, data);
    await fs.unlinkSync(file.path);
    return;
};
export default (req, res) => {
    if (req.method === 'POST') {
        const form = new formidable.IncomingForm();
        form.parse(req, async function (err, fields, files) {
            await saveFile(files.file);
            return res.status(201).send('');
        });
        post(req, res);
    }
};
复制代码

由于篇幅有限,删除了一些异常处理代码。这里我们使用 formidable 来解析 FormData,注意由于 next.js 默认会启用 bodyParser,所以需要 config 中显示的禁用 bodyParser

formidable 会将文件放到一个临时目录中,我们直接从临时目录读取该文件然后存到指定目录即可,注意转存完成后使用 unlink 释放缓存文件,也可以直接使用 rename 移动文件位置。

await fs.renameAsync(file.path, `./public/${file.name}`);
复制代码

这样一个简单的文件上传功能就完成了,而如果使用原生 node 的话差别不大:

http.createServer(function (req, res) {
    if (req.url == '/api/file' && req.method === 'POST') {
        const form = new formidable.IncomingForm();
        form.parse(req, async function (err, fields, files) {
            await saveFile(files.file);
            return res.status(201).send('');
        });
        post(req, res);
    }
}).listen(3000);
复制代码

只是需要自己判断路由地址,实现代码并无差别。

文件下载

实现完了文件上传,我们再看下文件下载,文件下载其实只需要实现一个静态文件服务器即可,最简单的办法是通过流管道了:

export default (req, res) => {
    if (req.method === 'GET') {
        const filePath = path.join(process.env.FILE_PATH, req.url);
        const readStream = fs.createReadStream(filePath);
        readStream.pipe(res);
        readStream.on('finish', () => {
            readStream.close();
        });
    }
};
复制代码

我们直接将文件读取流通过管道接到相应中,即可完成文件下载。node 端代码和上面上传相同,只是做路径上的识别,别的并无差别。

此外我们还可以通过直接发送文件内容的方式来返回文件,下面为原生 node 代码示例:

const fileContent = fs.readFileSync(filePath);
res.writeHead(200, { 'Content-Type': contentType });
res.end(content, 'utf-8');
复制代码

而在页面上我们只需要使用 a 标签的 download,即可实现下载,也可以通过 window.open 等其它方式,不过要注意做好防拦截处理:

<a download="fileName.png" href="/node/static/fileName.png">点击下载</a>
复制代码

总结

node 端实现文件上传和下载的难度并不大,但是要额外注意的是安全隐患等问题,避免被恶意上传木马,这块后面会单独写一篇。

相关文章
|
JavaScript API
NodeJs——使用axios下载上传文件
NodeJs——使用axios下载上传文件
463 4
|
9月前
|
JavaScript Unix Linux
nvm与node.js的安装指南
通过以上步骤,你可以在各种操作系统上成功安装NVM和Node.js,从而在不同的项目中灵活切换Node.js版本。这种灵活性对于管理不同项目的环境依赖而言是非常重要的。
2803 11
|
弹性计算 JavaScript 前端开发
一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
Node.js 是一种高效的 JavaScript 运行环境,基于 Chrome V8 引擎,支持在服务器端运行 JavaScript 代码。本文介绍如何在阿里云上一键部署 Node.js 环境,无需繁琐配置,轻松上手。前提条件包括 ECS 实例运行中且操作系统为 CentOS、Ubuntu 等。功能特点为一键安装和稳定性好,支持常用 LTS 版本。安装步骤简单:登录阿里云控制台,选择扩展程序管理页面,安装 Node.js 扩展,选择实例和版本,等待创建完成并验证安装成功。通过阿里云的公共扩展,初学者和经验丰富的开发者都能快速进入开发状态,开启高效开发之旅。
|
存储 JavaScript 搜索推荐
Node框架的安装和配置方法
安装 Node 框架是进行 Node 开发的第一步,通过正确的安装和配置,可以为后续的开发工作提供良好的基础。在安装过程中,需要仔细阅读相关文档和提示,遇到问题及时解决,以确保安装顺利完成。
1150 155
|
资源调度 JavaScript 前端开发
前端开发必备!Node.js 18.x LTS保姆级安装教程(附国内镜像源配置)
本文详细介绍了Node.js的安装与配置流程,涵盖环境准备、版本选择(推荐LTS版v18.x)、安装步骤(路径设置、组件选择)、环境验证(命令测试、镜像加速)及常见问题解决方法。同时推荐开发工具链,如VS Code、Yarn等,并提供常用全局包安装指南,帮助开发者快速搭建高效稳定的JavaScript开发环境。内容基于官方正版软件,确保合规性与安全性。
12684 23
|
JavaScript 前端开发 数据可视化
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
842 2
【01】Cocos游戏开发引擎从0开发一款游戏-cocos环境搭建以及配置-Cocos Creator软件系统下载安装-node环境-优雅草卓伊凡
|
弹性计算 JavaScript 前端开发
一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
一键安装!阿里云新功能部署Nodejs环境到ECS竟然如此简单!
|
JavaScript
nodejs安装之npm ERR! code CERT_HAS_EXPIREDnpm ERR! errno CERT_HAS_EXPIRED reason: certificate has expired-证书错误通用问题解决方案-优雅草央千澈
nodejs安装之npm ERR! code CERT_HAS_EXPIREDnpm ERR! errno CERT_HAS_EXPIRED reason: certificate has expired-证书错误通用问题解决方案-优雅草央千澈
3294 27
|
数据库
【YashanDB知识库】安装共享集群时报错:YAS-05721 invalid input parameter, reason: node name invalid
【YashanDB知识库】安装共享集群时报错:YAS-05721 invalid input parameter, reason: node name invalid
|
Web App开发 JavaScript 前端开发
2024年5月node.js安装(winmac系统)保姆级教程
本篇博客为2024年5月版Node.js安装教程,适用于Windows和Mac系统。作者是一名熟悉JavaScript与Vue的大一学生,分享了Node.js的基本介绍、下载链接及简单安装步骤。安装完成后,通过终端命令`node -v`验证版本即可确认安装成功。欢迎关注作者,获取更多技术文章。
895 2
2024年5月node.js安装(winmac系统)保姆级教程