简洁的网站案例,vr技术在网站建设的应用,网站怎么发外链,专业建设思路文件上传
文件上传的方案#xff1a;
大文件上传#xff1a;将大文件切分成较小的片段#xff08;通常称为分片或块#xff09;#xff0c;然后逐个上传这些分片。这种方法可以提高上传的稳定性#xff0c;因为如果某个分片上传失败#xff0c;只需要重新上传该分片而…文件上传
文件上传的方案
大文件上传将大文件切分成较小的片段通常称为分片或块然后逐个上传这些分片。这种方法可以提高上传的稳定性因为如果某个分片上传失败只需要重新上传该分片而不需要重新上传整个文件。同时分片上传还可以利用多个网络连接并行上传多个分片提高上传速度断点续传在上传过程中如果网络中断或上传被中止断点续传技术可以记录已成功上传的分片信息以便在恢复上传时继续上传未完成的部分而不需要重新上传整个文件。这种技术可以大大减少上传失败的影响并节省时间和带宽。
前端实现
headmeta charsetUTF-8titleTitle/titlestyleinput {background-color: #f5f5f5;border: 1px solid #ccc;border-radius: 5px;cursor: pointer;outline: none;font-size: 14px;color: #333;text-align: center;line-height: 30px;font-size: 40px;}/style
/head
body!-- 上传文件 --input typefile idfile namefile value上传文件 /
/body第一步获取元素监听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}第二步将这些分片的文件片编入编号和文件名后以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)})}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})}
})放到接口上面就可以将分完片的文件上传
// 2. 配置multer
const upload multer({storage:storage})
// 3. 创建上传接口
app.post(/upload,upload.single(file),(req,res) {res.send(上传成功)
})合并文件先读取分片文件的文件名然后把这些文件重新的进行排序合成一个新的文件
完整代码
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))文件流下载
文件流下载是一种通过将文件内容以流的形式发送给客户端实现文件下载的方法。它适用于处理大型文件或需要实时生成文件内容的情况。
nodejs端实现
响应头
Content-Type 指定下载文件的 MIME 类型 application/octet-stream二进制流数据application/pdfAdobe PDF 文件。application/jsonJSON 数据文件image/jpegJPEG 图像文件 Content-Disposition 指定服务器返回的内容在浏览器中的处理方式。它可以用于控制文件下载、内联显示或其他处理方式 attachment指示浏览器将响应内容作为附件下载。通常与 filename 参数一起使用用于指定下载文件的名称inline指示浏览器直接在浏览器窗口中打开响应内容如果内容是可识别的文件类型例如图片或 PDF则在浏览器中内联显
代码实现
import express from express
import fs from fs
import path from path
import cors from corsconst 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.fileNameif(!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))前端逻辑
前端核心逻辑就是接受的返回值是流的方式arrayBuffer,转成blob生成下载链接模拟a标签点击下载
!DOCTYPE html
html langen
headmeta charsetUTF-8titleTitle/titlestyleinput {background-color: #f5f5f5;border: 1px solid #ccc;border-radius: 5px;cursor: pointer;outline: none;font-size: 14px;color: #333;text-align: center;line-height: 30px;font-size: 40px;}/style
/head
body!-- 上传文件 --input typebutton value下载文件 /
/body
scriptlet btn document.querySelector(input);btn.onclick function () {fetch(http://localhost:3000/upload,{method:POST,headers:{Content-Type:application/json},body:JSON.stringify({fileName:1.png,})}).then(res res.arrayBuffer()).then(res {// 1. 转为bloblet blob new Blob([res],{type:image/png})// 2. 创建a标签let a document.createElement(a)// 4. 设置a标签的href属性为blob地址a.href URL.createObjectURL(blob)// 3. 设置下载文件名a.download 1.png// 5. 模拟点击a标签a.click()// 6. 移除a标签a.remove()})}
/script
/html