常见的先后端交互数据大部分都是json格式的数据,可是当涉及到图片、文件上传时,就须要用到form-data
格式的数据,之前咱们要把input
标签的type属性设置为file格式,采用form提交的方式 须要把form的enctype
属性设置为multipart/form-data
,采用js提交的方式咱们就须要手动new一个FormData
对象,对其加工处理以后再提交。在javascript已经蔓延至多领域的今天, 咱们将从一个最简单的例子入手,去实现一个完整的图片上传功能。javascript
首先,初始化一个express项目,这部分就不赘述,初始化项目见express文档,以后新建app.js启动文件和public文件夹用户存放静态页面。css
//app.js
var express = require('express');
var app = express();
app.get('/', function (req, res) {
res.send('Hello World!');
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
复制代码
此时,运行node app.js
,便可在localhost:3000
浏览express项目。html
<!--public/upload.html-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>请上传您的文件</title>
</head>
<body>
<form action="/upload" enctype="multipart/form-data" method="post">
<input type="file" name="upload" id="upload" multiple="multiple" value="" />
<input type="submit" name="" id="" value="点击上传" />
</form>
</body>
</html>
复制代码
此页面经过文件类型的input上传文件,并经过form提交formdata格式的数据。前端
<!--public/result.html-->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>上传成功</title>
</head>
<body>
<h1>上传成功</h1>
<img src="/public/test.png" />
</body>
</html>
复制代码
此页面为上传文件后的反馈页面,预览上传的图片。java
In Express 4, req.files is no longer available on the req object by default. To access uploaded files on the req.files object, use multipart-handling middleware like busboy, multer, formidable, multiparty, connect-multiparty, or pez.node
因为在新版本express 4中,req.files
不可用,因此咱们须要借助npm包,这里咱们借助的是formidable
,请自行安装。数据库
var express = require('express');
var app = express();
// 引入解析包
var formidable = require('formidable');
fs = require('fs');
app.get('/', function (req, res) {
res.send('Hello World!');
});
// 设置静态文件目录
app.use('/public', express.static('public'));
app.post('/upload', function(req,res){
var form = new formidable.IncomingForm();
console.log('about to parse');
form.parse(req, function(error, fields, files){
console.log('parse done')
console.log(files.upload.path);
// 读取文件流并写入到public/test.png
fs.writeFileSync('public/test.png', fs.readFileSync(files.upload.path));
//重定向到结果页
res.redirect('/public/result.html');
})
});
app.listen(3000, function () {
console.log('Example app listening on port 3000!');
});
复制代码
** 这个简单的图片上传案例,能够更好的帮助咱们了解图片上传的流程,下面咱们借助element-ui的upload组件还原真实项目的案例。**express
<template>
<el-upload class="avatar-uploader" action="/api/upload" :show-file-list="false" :on-success="handleUploadSuccess" :before-upload="beforeAvatarUpload" > <img v-if="imgurl" :src="imgurl" class="avatar"> <i v-else class="el-icon-plus avatar-uploader-icon"></i> </el-upload> </template> <script> export default { data() { return { imgurl: '' } }, methods: { handleAvatarSuccess(res, file) { this.imgurl = URL.createObjectURL(file.raw); }, beforeAvatarUpload(file) { // 上传前对文件的一些校验处理 } }, mounted(){ } } </script> <style> .avatar-uploader .el-upload { border: 1px dashed #d9d9d9; border-radius: 6px; cursor: pointer; position: relative; overflow: hidden; } .avatar-uploader .el-upload:hover { border-color: #409EFF; } .avatar-uploader-icon { font-size: 28px; color: #8c939d; width: 178px; height: 178px; line-height: 178px; text-align: center; } .avatar { width: 178px; height: 178px; display: block; } </style> 复制代码
let path = require('path');
let express = require('express');
let router = express.Router();
let formidable = require('formidable');
router.post('/', function(req, res, next){
let form = new formidable.IncomingForm();
form.encoding = 'utf-8'; // 编码
// 保留扩展名
form.keepExtensions = true;
//文件存储路径 最后要注意加 '/' 不然会被存在public下
form.uploadDir = path.join(__dirname, '../public/images/');
// 解析 formData 数据
form.parse(req, (err, fields ,files) => {
if(err) return next(err)
let imgPath = files.file.path;
let imgName = files.file.name;
console.log(imgName, imgPath);
// 返回路径和文件名
res.json({code: 1, data: { name: imgName, path: imgPath }});
})
});
module.exports = router;
复制代码
到这里,咱们和上面的简单案例对比一下,其实差异并不大,变动的只是最后的数据响应,固然这个案例也只应用于图片上传成功,前端获取到返回的图片地址,而后再和其余的字段一块儿提交给服务端的状况,若是是上传即对数据库的数据作修改,好比说:头像修改, 就须要在响应数据返回前对数据库进行操做修改。npm
let path = require('path');
let express = require('express');
let router = express.Router();
// 导入用户信息模型
let User = require('../models/UserModel');
let formidable = require('formidable');
router.post('/', function(req, res, next){
let form = new formidable.IncomingForm();
form.encoding = 'utf-8'; // 编码
// 保留扩展名
form.keepExtensions = true;
//文件存储路径 最后要注意加 '/' 不然会被存在public下
form.uploadDir = path.join(__dirname, '../public/images/');
// 解析 formData 数据
form.parse(req, (err, fields ,files) => {
if(err) return next(err);
//借助username字段进行数据查询
let username = fields.username;
let imgPath = files.file.path;
let imgName = files.file.name;
console.log(imgName, imgPath);
User.updateOne({username: username},{photo: imgPath}, (err, data) => {
if(err) return next(err);
// 返回处理结果
res.json({code: 1, data: data});
})
})
});
module.exports = router;
复制代码