文件上传
服务器路由:
// ./routes/students.js
const express = require('express');
const router = express.Router();
const multer = require('multer');
const path = require("path")
const fs = require("fs");
const { rootPath } = require("../utils/baseInfo")
const upload = multer({ dest: path.join(rootPath, "/public/images/headPic") });//**
// 文件上传接口
router.post('/upload', upload.single('file'), async function (req, res, next) {//**
//其中'file'是文件上传的key
const originalname = req.file.path;
const newname = originalname + path.extname(req.file.originalname);
fs.rename(originalname, newname, error => {
if (error) throw error;
const responsename = newname.replace(rootPath + `${path.sep}public${path.sep}`, "");//
res.send(responsename);
})
});
// 文件删除接口
router.post('/deletePic', async function (req, res, next) {//**
const { file } = req.body;
fs.unlink(path.join(rootPath, "public", file), function (err) {
if (err) res.send(false);
else res.send(true);
})
});
module.exports = router;
服务器工具模块,用来保存项目根目录
//. ./util/baseInfo.js
const path = require("path");
const os = require("os")
// os.type()
// 在 Linux 上返回 'Linux',在 macOS 上返回 'Darwin',在 Windows 上返回 'Windows_NT'。
module.exports = {
rootPath:path.join(/window/i.test(os.type())?"":"/",path.resolve(__dirname,"../"))//项目根路径
}
客户端文件本地显示代码:
function getFileURL(file) {//该方法用来获取文件在浏览器中的缓存地址,实现本地显示
var getUrl = null;
if (window.createObjectURL != undefined) { // basic
getUrl = window.createObjectURL(file);
} else if (window.URL != undefined) { // mozilla(firefox)
getUrl = window.URL.createObjectURL(file);
} else if (window.webkitURL != undefined) { // webkit or chrome
getUrl = window.webkitURL.createObjectURL(file);
}
return getUrl;
}
// ./views/students/update.js-->handler
//监听文件上传的input事件,用于本地显示图片
$(document).on("input", ".update-head-pic-file", function () {
const file = this.files[0];
if (file) $(this).nextAll("img").attr("src", getFileURL(file));
});
客户端文件上传ajax原生实现:
function upload(url,keyName,file) {
//url:上传的服务器接口。
//keyName:上传的文件的key。
//file:上传的文件(由input[type='file']获取)
return new Promise(r => {
const fd = new FormData();
fd.append(keyName, file);//键的名字必须与服务器对应
$.ajax({
url:"xxxxxx",
type: "post",//***
data: fd,//***
cache: false,//上传文件无需缓存
contentType: false,//*** //数据的解析类型,不需要,我们上传2进制数据,没有类型
processData: false,//*** //用于对data参数进行序列化处理 这里必须false
success(data) {
r(data)
}
})
})
}
layui实现:
var uploadInst = upload.render({
elem: '#test1' //绑定元素
, url: '/students/upload/' //上传接口
,auto:false//自动上传,选择完图片立即上传
,field:"file"//文件上传的key,默认:“file”
,bindAction:"#sure"//非自动上传时,图片上传触发的按钮
, headers: { "Authorization": `Bearer ${localStorage.user_token}` }//jwt验证需要的请求头
, done: function (res) {
//上传完毕回调
}
, error: function () {
//请求异常回调
}
, choose(obj){
//将每次选择的文件追加到文件队列
var files = obj.pushFile();
//预读本地文件,如果是多文件,则会遍历。(不支持ie8/9)
obj.preview(function(index, file, result){
//==========该函数中可以实现图片预览
//通过getFileURL(file) 获取缓存地址,即可用于img标签显示
console.log(index); //得到文件索引
console.log(file); //得到文件对象
console.log(result); //得到文件base64编码,比如图片
//obj.resetFile(index, file, '123.jpg'); //重命名文件名,layui 2.3.0 开始新增
//这里还可以做一些 append 文件列表 DOM 的操作
//obj.upload(index, file); //对上传失败的单个文件重新上传,一般在某个事件中使用
//delete files[index]; //删除列表中对应的文件,一般在某个事件中使用
});
}
});
具体代码(这里是原生实现,我们最好改为腊鱼你实现):
// ./views/students/update.js
//添加
$("#tab-wrap-add").on("click", ".addBtn", async function () {
const $fileInput = $(".addStudentForm [type='file']");
const file = $fileInput[0].files[0];
if (file) {//file存在即上传
const headPic = await that.upload("/students/upload", "headPic", file);
$fileInput.prev().val(headPic);
}
const { status } = await that.add({ stu: layui.form.val("addStudent") })
if (status) {
layui.layer.msg("添加成功!");
} else {
layui.layer.msg("添加失败!");
}
})
// ./views/students/add.js
//更新
$("#tab-wrap-update").on("click", ".updateBtn", async function () {
const id = $(".updateStudentForm")[0].id.value;
const $fileInput = $(".updateStudentForm [type='file']");
const file = $fileInput[0].files[0];
//删除-start
const oldHeadPic = $(".updateStudentForm")[0].headPic.value;
if (oldHeadPic && file) {
await that.deletePic("/students/deletePic",oldHeadPic)
}
//删除-end
//文件上传-start
if (file) {//file存在即上传
const headPic = await that.upload("/students/upload", "headPic", file);
$fileInput.prev().val(headPic);
}
//文件上传-end
//上传成功后更新学生信息
const data = await that.update({ stu: $(".updateStudentForm").serialize(), id })
if (data.status) {
layui.layer.msg("修改成功!");
location.hash = "/info/list/学生信息";
} else {
layui.layer.msg("修改失败!");
}
})