前言:使用element上傳圖片以後,文件file下的url是blob:http//localhost:8080地址,後端很差處理css
問題如上圖所示html
採用比較笨的js解決方法,將bolb文件打開,讀取src屬性(這是一個base64的數據流),把src的內容一塊兒發送給後端。node
這是一個上傳圖片子組件demoajax
<template> <el-upload class="upload-demo" action="" ref="upload" :auto-upload='false' :on-change='changeUpload' accept="image/jpeg,image/gif,image/png,image/bmp"> <div size="small" class="upload_btn"><div style="height:40px"></div><i class="iconfont icon-jiahao"></i><p style="line-height:0">點擊上傳</p></div> </el-upload> </template> <script> export default { name: 'regShopImg', data () { return { imageUrl: '', imgthing: {} } }, props: ['imgN', 'nameN'], methods: { changeUpload (file, fileList) { console.log(file) // 判斷圖片大小 if (fileList[0].size < 1100000) { // 判斷圖片格式是否爲jpg,png,jepg,gif var fileName=fileList[0].name // var suffixIndex=fileName.lastIndexOf(".") // var suffix=fileName.substring(suffixIndex+1).toUpperCase() var suffix = fileName.substring(fileName.lastIndexOf(".")+1).toUpperCase() if (suffix=="BMP"||suffix=="JPG"||suffix=="JPEG"||suffix=="PNG"||suffix=="GIF") { this.fileList = fileList this.$nextTick( () => { var i = this.imgN let uploadLists = document.getElementsByClassName('el-upload-list') let uploadListsN = uploadLists[i] let uploadListLi = uploadListsN.children uploadListsN.setAttribute('style', 'position: absolute;height: 160px;margin-top: 0;margin-left: 300px;width: 260px;overflow: hidden') let liA = uploadListLi[0] // 試着獲取bolb裏面的數據------------S //獲取圖片的Blob值 function getImageBlob(url, cb) { var xhr = new XMLHttpRequest() xhr.open("get", url, true) xhr.responseType = "blob" xhr.onload = function() { if (this.status == 200) { if(cb) cb(this.response) } } xhr.send() } function preView(url){ let reader = new FileReader() getImageBlob(url, function(blob){ reader.readAsDataURL(blob) }) reader.onload = function(e) { // 獲取bolb裏面數據時,生成預覽 var img = document.createElement("img") img.src = e.target.result // 獲取bolb裏面數據時,生成預覽 let imgElement = document.createElement('img') imgElement.setAttribute('src', fileList[0].url) imgElement.setAttribute('style', 'max-width:100%;padding-left:0') if (liA.lastElementChild.nodeName !== 'IMG') { liA.appendChild(imgElement) } // 把base64的信息放到imgthing的file裏 file.base64 = e.target.result } } preView(fileList[0].url) // 試着獲取bolb裏面的數據-------------E // 不獲取bolb裏面數據時,生成預覽 // let imgElement = document.createElement('img') // imgElement.setAttribute('src', fileList[0].url) // imgElement.setAttribute('style', 'max-width:100%;padding-left:0') // if (liA.lastElementChild.nodeName !== 'IMG') { // liA.appendChild(imgElement) // } } ) // 修改nameN名字對應的數據,在一個頁面使用多個不一樣字段圖片上傳,爲了複用組件 if (this.nameN === 'identityCard_Z') { this.imgthing.identityCard_Z = file } if (this.nameN === 'identityCard_F') { this.imgthing.identityCard_F = file } if (this.nameN === 'identityCard_S') { this.imgthing.identityCard_S = file } this.$emit('imgthing', this.imgthing) } else { this.$message.error('文件類型不正確,請從新上傳!') } } else { this.$message.error('圖片大小超過1M,請從新上傳') } } } } </script> <style scoped lang="scss"> // 上傳 .upload-demo{width:260px;height:160px; .upload_btn{width:260px;height:160px;background:#f2f2f2} .el-upload__tip{margin:0;float:left} } </style>
父組件上傳demo後端
<template> <!-- 表單信息 --> <el-form :model="ruleForm" :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <!-- 第三步-提交資質內容 --> <div v-if="this.active === 3"> <el-form-item label="身份證號碼" prop="identityCard"> <el-input type="identity" v-model="ruleForm.identityCard" style="width:260px" placeholder="請輸入身份證號"></el-input> </el-form-item> <el-form-item label="身份證正面" prop="identityCard_Z"> <RegShopImg :imgN='0' :nameN='identityCard_Z' @imgthing = 'imgthing' v-model="ruleForm.identityCard_Z"></RegShopImg> </el-form-item> <el-form-item label="身份證反面" prop="identityCard_F"> <RegShopImg :imgN='1' :nameN='identityCard_F' @imgthing = 'imgthing' v-model="ruleForm.identityCard_F"></RegShopImg> </el-form-item> <el-form-item label="手持身份證" prop="identityCard_S"> <RegShopImg :imgN='2' :nameN='identityCard_S' @imgthing = 'imgthing' v-model="ruleForm.identityCard_S"></RegShopImg> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')" class="btn_submit">提 交 資 質</el-button> </el-form-item> </div> </el-form> </template> <script> import RegShopImg from '@/components/common/regShopImg' //上傳圖片的子組件 import Qs from 'qs' // post方式下引入qs插件字符串化傳輸信息 export default { name: 'regShop', data () { return { active: 3, // 分步驟走的斷定 ajaxRegisterUrl: '', // 註冊提交頁面 imgN: '', // 上傳信息的名字對應的index序號 nameN: '', // 上傳信息的名字 identityCard_Z: 'identityCard_Z', identityCard_F: 'identityCard_F', identityCard_S: 'identityCard_S', Imgthing: {}, //子組件上傳的信息 ruleForm: { // 提交信息的表單對象 identityCard_Z: '', identityCard_F: '', identityCard_S: '', }, rules: { // 必填斷定規則 identityCard_Z: [ {required: true, message: '請上傳身份證正面圖片', trigger: 'blur'} ], identityCard_F: [ {required: true, message: '請上傳身份證反面圖片', trigger: 'blur'} ], identityCard_S: [ {required: true, message: '請上傳手持身份證圖片', trigger: 'blur'} ] } } }, methods: { // 第三步:證件照片上傳 imgthing (imgthing) { // 合併對象 this.Imgthing = Object.assign(this.Imgthing, imgthing) // 填充到ruleForm對應項,用來判斷是否有數據 this.ruleForm.identityCard_Z = this.Imgthing.identityCard_Z this.ruleForm.identityCard_F = this.Imgthing.identityCard_F this.ruleForm.identityCard_S = this.Imgthing.identityCard_S }, // 總表單提交 submitForm (formName) { this.$refs[formName].validate((valid) => { if (valid) { // 因爲base64的數據流比較大,get方式放不下,必須採用post方式 let data = Qs.stringify(this.ruleForm) this.$ajax.post(this.ajaxRegisterUrl, data) .then((res) => { console.log(res) if (res.status === 1) { this.$message.success('恭喜您,註冊成功!') } }) } else { this.$message.error('提交資料有誤,註冊失敗!') return false } }) } }, components: { 'RegShopImg': RegShopImg } } </script> <style scoped lang="scss"> </style>
多添加了一個base64的數據app
另外一種思路是利用element已有的方式,將圖片上傳和表單上傳分開。ide
圖片上傳只上傳文件,利用上傳成功handleAvatarSuccess(res, file)的方法,獲取後端對上傳圖片存儲位置的路徑,並將其傳給父組件。提交表單的時候,提交圖片部分僅僅是路徑。post
1.js 獲取圖片url的Blob值並預覽:https://www.cnblogs.com/tujia/p/6483255.html ui