express實現圖片上傳

常見的先後端交互數據大部分都是json格式的數據,可是當涉及到圖片、文件上傳時,就須要用到form-data格式的數據,之前咱們要把input標籤的type屬性設置爲file格式,採用form提交的方式 須要把form的enctype屬性設置爲multipart/form-data,採用js提交的方式咱們就須要手動new一個FormData對象,對其加工處理以後再提交。在javascript已經蔓延至多領域的今天, 咱們將從一個最簡單的例子入手,去實現一個完整的圖片上傳功能。javascript

初始化express項目

首先,初始化一個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

配置upload API

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

upload上傳組件

<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> 複製代碼

upload API邏輯編寫

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;
複製代碼
相關文章
相關標籤/搜索