上传文件
1.form表单上传
<form action="/uploadHead" method="POST" enctype="multipart/form-data" class="layui-form"> <!-- accept="image/*" 指规定文件只能选择图片类型的文件 --> <input type="file" name="headImg" accept="image/*" > <button>上传头像</button> </form>
action="/uploadHead" 接口名字
method="POST" 请求方式
enctype设置表单提交的数据类型
multipart/form-data指文件类型
2.ajax文件上传
layui.use(["form", "jquery", "layer"], function () { var form = layui.form; var $ = layui.jquery; var layer = layui.layer; form.on("submit", function () { console.log($("input")[0].files) // 找到input选中的头像文件 var file = $("input")[0].files[0] // 把需要上传的文件加入formData对象中(因为ajax上传的是formData对象) var formData = new FormData() // 注意: 第一个参数是input的name值,和后端存储参数对应 formData.append("headImg", file); // formData.append("username", sessionStorage.getItem("name")) // 发起ajax请求, 上传头像 $.ajax({ type: "post", url: "/uploadHead", data: formData, // contentType指上传数据类型, jQuey封装ajax时会自动把data对象转成字符串类型, false表示禁止自动转换类型, 因为文件不能转类型 contentType: false, // processData指jQuery内部对data数据的加工处理(编码),false可防止文件被加工处理, 保持原有结构 processData: false, success: function () { layer.msg("头像已上传", { icon: 1 }) window.parent.document.getElementById("headImg").src = "./HeadImg/" + sessionStorage.getItem("name") + ".jpg?" + Math.random() } }) return false; }) })
注意: data: formData,要写 contentType指上传数据类型, jQuey封装ajax时会自动把data对象转成字符串类型, false表示禁止自动转换类型, 因为文件不能转类型 contentType: false,要写 processData指jQuery内部对data数据的加工处理(编码),false可防止文件被加工处理, 保持原有结构
// 注意!!!!! window.parent.document.getElementById("headImg").src = "./HeadImg/张三.jpg" 这一句无效的原因: img标签设置src地址时,如果src值不变的情况下, img会直接调用缓存, 不会更新 (浏览器自动缓存造成的结果) 解决方案: 我们在src图片路径后使用?拼接随机数,使设置前后的src不一致, img就会重载图片 (?后的数据叫hash值,不影响路径使用)
3.后端接收文件接口
3.1首先导入硬盘存储模块
var multer = require("multer");
3.2设置文件存储位置和文件名
var myStorage = multer.diskStorage({ // 设置文件存储位置 destination: function(req, file, callback){ // 通过调用callback设置文件存储目录, 参数1是错误信息, 参数2是目录 callback(null,"./public/HeadImg") }, // 设置文件名 filename: function(req, file, callback){ // file.originalname 指文件的原始名 // callback(null, file.originalname) // 把用户头像名设置为用户名, 保证每个用户头像唯一不重复 // console.log(1, req.body) // 在磁盘存储时,body-parser模块尚未解析出body数据,所以这里body为空 // callback(null, req.body.username + ".jpg") // 结论: 这种方案不可行 // cookie会随ajax请求,被携带在请求头中, 但请求头不支持汉字,会乱码, 所以在本地cookie中存数据时, 汉字要进行url编码, // 使用cookie-parser模块可以直接解析请求头中的cookie字符串, 自动解码并生成对象存入req.cookies字段中 console.log(1, req.headers.cookie, req.cookies) callback(null, req.cookies.username + ".jpg") } // 以上两个函数都有三个参数: // req: 请求对象, 对应接口回调中的req参数 // file: 上传的文件信息 // callback: 设置信息的回调, 通过向callback传参设置文件名和位置 }) // 以上两个函数都有三个参数: // req: 请求对象, 对应接口回调中的req参数 // file: 上传的文件信息 // callback: 设置信息的回调, 通过向callback传参设置文件名和位置
3.3创建硬盘存储对象
var save = multer({ storage: myStorage })
3.4请求接口实现
app.post("/uploadHead", save.single("headImg"), function(req, res){ console.log(2, req.body) // 文件上传的回调执行时, 文件就已经存储到磁盘了, 直接响应即可 res.json({code: 1, msg: "头像已上传"}) })