開場白
在平時的業務中,我們很多使用都會有檔案上傳這個功能。
今天分享一下使用 node+element-ui實現一下檔案上傳。
請個人大佬指點一番~~~。批評的時候稍微輕一點。
畢竟我心裡承受能力弱地一批,一不高興就喜歡....
使用 element-ui庫el-upload元件fil型別上傳
前端上傳檔案的時候,我們通常file物件。
較小的圖片的當然也可以使用base64的方式進行上傳。
等會我們將會將file轉化為base64。
file物件傳參的時候是這樣的 file:file(二進位制物件)
並且'Content-type': 'multipart/form-data'
下面我們使用 element-ui 的el-upload 元件進行檔案上傳.
我們會使用 http-request 自定義事件覆蓋原來的事件。
請看下面的程式碼
<template>
<div>
<h2>檔案上傳</h2>
<el-upload class="upload-demo" action="https"
:http-request="uploadFile">
<el-button size="small" type="primary">點選上傳</el-button>
</el-upload>
</div>
</template>
<script>
import axios from 'axios'
export default {
methods: {
uploadFile(file) {
console.log('file物件', file)
axios.post('http://127.0.0.1:666/upload/upload',
{
file:file
}, {
'Content-type': 'multipart/form-data'
}
).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
}
}
}
</script>
寫過很多檔案上傳的的小夥伴。
你們覺得可以上傳成功嗎?
會是file:file(二進位制)物件嗎?
憑藉自己的感覺想一分鐘,然後下滑
為什麼傳參的是 file:{...},而不是file:file(二進位制)
有的小夥伴會說 你傳的時候不應該是file,應該是file.file
因為從你剛剛的截圖來看應該是:file.file才是我們需要的。
感覺說的有道理,我們嘗試一下。
使用FormData來解決這個問題
FormData是XMLHttpRequest提供的一個介面物件,
用以將資料編譯成鍵值對,以便於XMLHttpRequest來傳送資料。
建立一個 FormData物件,並新增屬性。
FormData 可以透過 append(key, value)來新增資料。
上面說了 FormData的簡單介紹。
並沒有說為啥FormData可以使用解決這個這個問題?
那為什麼FormData可以解決這個問題了?
因為:
File 介面基於 Blob,繼承 blob 功能並將其擴充套件為支援使用者系統上的檔案。
你可以透過 Blob() 建構函式建立一個 Blob 物件。
而 FormData 物件附加 File 或 Blob 型別的檔案,所以我們可以新增。
<script>
import axios from 'axios'
export default {
methods: {
uploadFile(file) {
let formdata = new FormData();
console.log(file);
formdata.append("file", file.file);
axios.post('http://127.0.0.1:666/upload/upload',
formdata, {
'Content-type': 'multipart/form-data'
}
).then(function (response) {
console.log(response);
}).catch(function (error) {
console.log(error);
});
}
}
}
</script>
將file轉為base64
<template>
<div>
<!-- accept 接收圖片格式 -->
<input type="file" title="" ref="inputRef"
accept=".jpeg,.png, .gif,.jpg" @change="Upload">
</div>
</template>
<script>
import axios from 'axios'
export default {
methods: {
// 檔案上傳被觸發
Upload(event) {
const flie = event.target.files[0]; //直接獲取的就是file物件
this.fileChangeBase64(flie).then(backres => {
console.log('base64', backres)
// 上傳成功後的處理,清除input中value值,否則只相同檔案只能夠上傳一次
// this.$refs.inputRef.value = ""; 在合適的時候使用
}).catch(err => {
console.log('err', err )
})
},
// 將file物件轉化為base64
fileChangeBase64(file) {
return new Promise((resolve, reject) => {
//FileReader類就是專門用來讀檔案的,我們現在建立一個
const reader = new FileReader()
// 它的本質就是圖片的二進位制資料, 進行base64加密後形成的一個字串.
reader.readAsDataURL(file)
// 成功返回對應的資訊,reader.result一個base64
reader.onload = () => resolve(reader.result)
// 失敗返回失敗的資訊
reader.onerror = error => reject(error)
})
}
}
}
</script>
需要注意的一點,我這裡是將file轉為base64哈。
base64將不會不能被multer處理的哈~或者說不能夠處理
node中介軟體 multer 的簡單介紹
前端程式碼已經寫好了,現在我們開始寫後端的程式碼,後端我們使用node+express
multer 是一個 node.js 中介軟體。
它用於處理 multipart/form-data 型別的表單資料,它主要用於上傳檔案。
需要注意的是: multer 不會處理任何非 multipart/form-data 型別的表單資料。
換一句換說:前端必須這樣設定型別 'Content-type': 'multipart/form-data'
guthub官方解釋連結
https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md
下載 multer
前端程式碼寫好了,現在我們開始藉助node來實現後端的程式碼
我們使用 multer 來進行檔案傳
第一步:先下載 multer 模組
npm i express multer -S
我下載的時候是1.4.5版本
fileupload.js檔案
// 引入express
var express = require('express')
//新增路由模組
var router = express.Router()
// 檔案上傳需要的模組
var multer=require('multer')
// 配置路徑和檔名
var storage = multer.diskStorage({
//上傳檔案到伺服器的儲存位置
destination: 'public/upload',
filename: function (req, file, callback) {
//上傳的檔案資訊
console.log('file', file)
/**
* file {
fieldname: 'file',
originalname: 'JRMW5Y~E5B%UO4$EZ)[)XLR.png',
encoding: '7bit',
mimetype: 'image/png'
}
*/
// 將字串分割成為陣列,以點.的形式進行分割。返回的是一個陣列
var fileFormat = (file.originalname).split('.')
// 獲取時間戳
var filename = new Date().getTime()
// 檔案的命名為:時間戳 + 點 + 檔案的字尾名
callback(null, filename + "." + fileFormat[fileFormat.length-1])
}
})
var upload = multer({
storage
})
router.post('/upload', upload.single('file'), (req, res) => {
res.send({ code:'0', msg:'上傳成功'})
})
module.exports = router;
app.js 引入註冊路由
// 引入
var uploadRouter = require('./routes/fileupload');
// ... 其他程式碼....
//註冊介面字首/upload
app.use('/upload', uploadRouter);
//這個時候介面就是 /upload/upload
需要注意的點
1. 需要注意的點:upload.single('key') 必須要與前端中
formData.append("file", flie)key鍵名保持一致。
2. 為什麼不直接使用前端傳遞傳來的名稱?
因為有可能名稱會重複,這樣不好。
3. 因為前端上傳檔案的時候使用change事件進行監聽的。
注意在合適的時候清除它的value值,否者上傳相同的檔案change事件不會被觸發