学习node.js十三,文件的上传于下载

简介: 学习node.js十三,文件的上传于下载

文件上传
文件上传的方案:

大文件上传:将大文件切分成较小的片段(通常称为分片或块),然后逐个上传这些分片。这种方法可以提高上传的稳定性,因为如果某个分片上传失败,只需要重新上传该分片而不需要重新上传整个文件。同时,分片上传还可以利用多个网络连接并行上传多个分片,提高上传速度
断点续传:在上传过程中,如果网络中断或上传被中止,断点续传技术可以记录已成功上传的分片信息,以便在恢复上传时继续上传未完成的部分,而不需要重新上传整个文件。这种技术可以大大减少上传失败的影响,并节省时间和带宽。
前端实现








1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
第一步:获取元素,监听change事件。获取到文件的信息之后,利用file原型上面的 blob对象的slice方法来进行分割

// 获取文件,监听有无上传
const file = document.getElementById('file');
file.addEventListener('change', function (e) {
// 获取文件信息
const file = e.target.files[0];
const chunks = sliceFile(file);
uploadFile(chunks)
})
// 分片
function sliceFile(file, chunkSize = 1024 1024 3) {
let chunks = []
for (let i = 0; i < file.size; i+= chunkSize) {
chunks.push(file.slice(i, i + chunkSize))
}
return chunks
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
第二步:将这些分片的文件片,编入编号和文件名后以formData的格式上传,并且将结果放入promise.all这个方法中,如果全部成功的化,那么就调用合并函数,将这个视频进行合并

// 上传
function uploadFile(chunks) {
let list = []
for (let i = 0; i < chunks.length; i++) {
let formData = new FormData();
formData.append('index', i)
formData.append('name', "wenjian")
formData.append('file', chunks[i])
list.push(fetch("http://localhost:8080/upload", {
method: 'POST',
body: formData
}))
}
// 监听事件是否成功
Promise.all(list).then(res => {
// 发送合并请求
fetch("http://localhost:8080/merge", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: "ceshi.gif",
})
}).then(res => {
console.log(res)
}).catch(e => {
console.log(e)
})
}).catch(e=> {
console.log(e)
})
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
nodejs端实现
安装依赖

express 帮我们启动服务,并且提供接口
multer 读取文件,存储
cors 解决跨域
初始化 multer.diskStorage

destination 存储的目录
filename 存储的文件名(我是通过index-文件名存储的你也可以改)
// 1. 初始化multer
const storage = multer.diskStorage({
destination:function (req,file,cb) {
cb(null,'./upload')
},
filename:function (req,file,cb) {
cb(null,${req.body.index}-${req.body.name})
}
})
1
2
3
4
5
6
7
8
9
放到接口上面,就可以将分完片的文件上传

// 2. 配置multer
const upload = multer({storage:storage})
// 3. 创建上传接口
app.post('/upload',upload.single('file'),(req,res) => {
res.send('上传成功')
})
1
2
3
4
5
6
合并文件:先读取分片文件的文件名,然后把这些文件重新的进行排序,合成一个新的文件

完整代码:

import express from 'express'
import multer from 'multer'
import cors from 'cors'
import fs from 'node:fs'
import path from 'node:path'

// 1. 初始化multer
const storage = multer.diskStorage({
destination:function (req,file,cb) {
cb(null,'./upload')
},
filename:function (req,file,cb) {
cb(null,${req.body.index}-${req.body.name})
}
})
const app = express()
app.use(cors())
app.use(express.json())
// 2. 配置multer
const upload = multer({storage:storage})
// 3. 创建上传接口
app.post('/upload',upload.single('file'),(req,res) => {
res.send('上传成功')
})
// 4. 合并文件
app.post("/merge",(req,res) => {
if(!req.body.name) return res.send('文件名不能为空')
let uploadDir = "./upload"
// 读取分片文件
let files = fs.readdirSync(path.join(process.cwd(), uploadDir))
// 重新排序
files = files.sort((a,b) => a.split('-')[0] - b.split('-')[0])
// 合并文件
let writeDir = path.join(process.cwd(),"./video",${req.body.name})
files.forEach(item => {
fs.appendFileSync(writeDir,fs.readFileSync(path.join(process.cwd(),uploadDir,item)))
fs.unlinkSync(path.join(process.cwd(),uploadDir,item))
})
res.send('合并成功')
})
app.listen(8080,() => console.log('Server is running on port 8080'))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
文件流下载
文件流下载是一种通过将文件内容以流的形式发送给客户端,实现文件下载的方法。它适用于处理大型文件或需要实时生成文件内容的情况。

nodejs端实现
响应头

Content-Type 指定下载文件的 MIME 类型
application/octet-stream(二进制流数据)
application/pdf:Adobe PDF 文件。
application/json:JSON 数据文件
image/jpeg:JPEG 图像文件
Content-Disposition 指定服务器返回的内容在浏览器中的处理方式。它可以用于控制文件下载、内联显示或其他处理方式
attachment:指示浏览器将响应内容作为附件下载。通常与 filename 参数一起使用,用于指定下载文件的名称
inline:指示浏览器直接在浏览器窗口中打开响应内容,如果内容是可识别的文件类型(例如图片或 PDF),则在浏览器中内联显
代码实现:

import express from 'express'
import fs from 'fs'
import path from 'path'
import cors from 'cors'

const app = express()
app.use(cors())
app.use(express.json())
app.use(express.static(path.join(process.cwd(),"static")))

app.post("/upload", (req, res) => {
let fileName = req.body.fileName
if(!fileName) return res.send({message: "File name is required"})
let filePath = path.join(process.cwd(),"static", fileName)
let readStream = fs.readFileSync(filePath)
// 设置响应头
res.setHeader('Content-Type', 'application/octet-stream')
res.setHeader('Content-Disposition', 'attachment;filename=' + fileName)
res.send(readStream)
})

app.listen(3000,() => console.log('Server is running on port 3000'))

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
前端逻辑

前端核心逻辑就是接受的返回值是流的方式arrayBuffer,转成blob,生成下载链接,模拟a标签点击下载

<!DOCTYPE html>












相关文章
|
27天前
|
Web App开发 JavaScript 前端开发
如何学习JavaScript?
如何学习JavaScript?
38 5
|
26天前
|
JavaScript 前端开发 索引
JavaScript学习第二章--字符串
本文介绍了JavaScript中的字符串处理,包括普通字符串和模板字符串的使用方法及常见字符串操作方法如`charAt`、`concat`、`endsWith`等,适合前端学习者参考。作者是一位热爱前端技术的大一学生,专注于分享实用的编程技巧。
21 2
|
26天前
|
存储 JavaScript 前端开发
JavaScript学习第一章
本文档介绍了JavaScript的基础知识,包括其在网页中的作用、如何通过JavaScript动态设置HTML元素的CSS属性,以及JavaScript中的变量类型(`var`、`let`、`const`)和数据类型(基本数据类型与引用数据类型)。通过实例代码详细解释了JavaScript的核心概念,适合初学者入门学习。
47 1
|
2月前
|
JavaScript
webpack学习五:webpack的配置文件webpack.config.js分离,分离成开发环境配置文件和生产环境配置文件
这篇文章介绍了如何将webpack的配置文件分离成开发环境和生产环境的配置文件,以提高打包效率。
52 1
webpack学习五:webpack的配置文件webpack.config.js分离,分离成开发环境配置文件和生产环境配置文件
|
2月前
|
JavaScript
js学习--商品列表商品详情
js学习--商品列表商品详情
20 2
|
2月前
|
JavaScript
js学习--九宫格抽奖
js学习--九宫格抽奖
20 2
|
2月前
|
JavaScript
js学习--开屏弹窗
js学习--开屏弹窗
37 1
|
2月前
|
JavaScript
js学习--抽奖
js学习--抽奖
17 1
|
2月前
|
JavaScript
js学习--隔行换色
js学习--隔行换色
32 1
|
2月前
|
JavaScript 前端开发 应用服务中间件
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
vue前端开发中,通过vue.config.js配置和nginx配置,实现多个入口文件的实现方法
180 0