页面上传、下载文件思路流程
前端的工作:
1.先express脚手架搭建一下项目环境
2.先写静态页面
3.拖拽文件至指定框,发送ajax请求(文件数据用FormData对象存储)
4.ajax接收后端发送过来upload下载下载文件的文件目录,然后渲染到页面上 (a标签的download属性可以点击a标签下载文件)
后端的工作:
1.先配置路由 upload.js ,并导出路由模块
2.app.js文件中引入路由模块,并使用路由中间件 加载路由
3.使用multer第三方模块将文件存储在服务器的磁盘上,存储在/public/upload文件夹,便于用户下载
4.读取upload文件夹中的文件名,将读取到的目录名返回给前端
看注释 ! ! !
搭建的项目目录
upload.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
$(function(){
//拖拽事件
$(document).on('dragover',function(ev){
ev.preventDefault();//阻止移动持续触发事件
});
//放下事件
$('#box').on('drop',function(ev){
ev.preventDefault();//阻止打开放入的文件
//jq对event事件对象进行二次封装
// console.log(ev.originalEvent.dataTransfer.files);
let files=Array.from(ev.originalEvent.dataTransfer.files);//获得文件
//formData();表单数据,用来存储数据和发送数据
let form=new FormData();
// console.log(form);
files.forEach((elm,i)=>{
console.log(elm);
//遍历所有文件,加入到formData里
form.append(`file${i}`,elm);//form.append();方法里面存的是键值对,键是文件名,值是存的数据
$('#fileslist').append(`<li>${elm.name}<span class='right'>${(elm.size/1024).toFixed(2)}KB</span></li>`);
});
// console.log(form);//数据是有的,就是看不到,所以就让其显示在页面上
//----------------------------上面部分我们已经存好了文件,也知道拖了哪些文件
//----------------------------下面部分就是上传文件,ajax发请求
$.ajax({
type:'post',//注意:文件的传输操作没有get方式
url:'http://localhost:3000/upload',
data:form,// formDate发送文件 需要下面两个属性
processData:false,
contentType:false,
success:function(res){
console.log(res);
}
})
});
$.ajax({
type:'post',
url:'http://localhost:3000/upload',
dataType:'json',
success:function(data){//数据渲染到页面上
// console.log(data);
let tempstr='';
data.forEach((elm,i)=>{
tempstr+=`
<li><a href='http://localhost:3000/upload/${elm}' download='${elm}'>${elm}</a></li>
`;
});
$('.mulu').append(tempstr);
}
})
})
</script>
<style>
* {
padding: 0;
margin: 0;
box-sizing: border-box;
}
#box {
width: 800px;
height: 400px;
border: 5px dashed darkblue;
margin: 0 auto;
text-align: center;
line-height: 400px;
font-size: 2em;
user-select: none;
color: #ccc;
}
#fileslist {
width: 800px;
margin: 0 auto;
padding: 5px;
list-style: none;
}
.left {
float: left;
}
.right {
float: right;
}
</style>
</head>
<body>
<div id="box">
请将需要上传的文件拖至此处
</div>
<ul id="fileslist">
</ul>
<ul class="mulu">
</ul>
</body>
</html>
readdir.js
//读取文件目录的模块
const fs=require('fs');
const path=require('path');
function readFile(){
return new Promise((resolve,reject)=>{
//读文件
fs.readdir(path.join(__dirname, '..',...arguments), (err, files) => {
if (err) reject(err);
resolve(files);
});
})
};
module.exports=readFile;
upload.js——配置的路由文件
const express=require('express');
const path=require('path');
const multer=require('multer');//nodejs中间件,专门用来处理form-data数据
//1.先配置路由
//需要将文件存储在服务器的磁盘上,怎么存储呢?
//DiskStorage 磁盘
//为什么要搞这个路径?
//因为你要下载文件,那么文件就必须先存储在服务器的磁盘上,用户能访问到的目录路径下,public
let url=path.join(__dirname,'..','public','upload');
let storage = multer.diskStorage({
destination: function (req, file, cb) {//目的地
cb(null, url)//回调函数,存储的目录
},
filename: function (req, file, cb) {
cb(null, file.fieldname + '-' + Date.now()+'.'+file.originalname.split('.').pop());//拼接后缀名
}
})
let upload = multer({ storage: storage })
const router=express.Router();//创建一个路由对象
router.post('/',upload.any(),(req,res,next)=>{//upload.any()接受所有类型的文件
console.log('接受到请求');
console.log(req.files);//接收到前端发过来的文件
readFile('public','upload').then(data=>{
res.send(data);//将文件目录发送给前端
})
});
module.exports=router;
app.js
// 引入路由模块
var uploadRouter=require('./routes/upload');
// 使用路由中间件 加载路由
app.use('/upload',uploadRouter);
在终端开启服务,即可上传文件并且下载文件(执行命令npm start)
建议:npmscript中node改为nodemon应用程序。
效果图: