Vue实现手动ajax上传并将文件转成Base64编码字符串传给后端

Vue实现手动ajax上传并将文件转成Base64编码字符串传给后端

最近初学vue项目中要用到上传功能,因为element-ui默认通过action上传,不够灵活,看了官方文档之后,改用其中属性http-request实现自定义上传(http-request: 覆盖默认的上传行为,可以自定义上传的实现)

前端计算MD5 可以使用插件 js-spark-md5,下载 spark-md5.min.js 存储在本地。

这里还应用到了大多数浏览器都实现了的类 FileReader,它的实例的 readAsDataURL方法,用来读取文件的base64编码以表示所读取文件的内容。FileReader——readAsDataURL。

先贴一下element-ui Upload 上传的属性

参数 说明 类型 默认值
action 必选参数,上传的地址 string
headers 设置上传的请求头部 object
multiple 是否支持多选文件 boolean
data 上传时附带的额外参数 object
name 上传的文件字段名 string file
with-credentials 支持发送 cookie 凭证信息 boolean false
show-file-list 是否显示已上传文件列表 boolean true
drag 是否启用拖拽上传 boolean false
accept 接受上传的文件类型(thumbnail-mode 模式下此参数无效) string
on-preview 点击文件列表中已上传的文件时的钩子 function(file)
on-remove 文件列表移除文件时的钩子 function(file, fileList)
on-success 文件上传成功时的钩子 function(response, file, fileList)
on-error 文件上传失败时的钩子 function(err, file, fileList)
on-progress 文件上传时的钩子 function(event, file, fileList)
on-change 文件状态改变时的钩子,添加文件、上传成功和上传失败时都会被调用 function(file, fileList)
before-upload 上传文件之前的钩子,参数为上传的文件,若返回 false 或者返回 Promise 且被 reject,则停止上传。 function(file)
before-remove 删除文件之前的钩子,参数为上传的文件和文件列表,若返回 false 或者返回 Promise 且被 reject,则停止删除。 function(file, fileList)
list-type 文件列表的类型 string text/picture/picture-card
auto-upload 是否在选取文件后立即进行上传 boolean true
file-list 上传的文件列表, 例如: [{name: ‘food.jpg’, url: ‘https://xxx.cdn.com/xxx.jpg’}] array
http-request 覆盖默认的上传行为,可以自定义上传的实现 function
disabled 是否禁用 boolean false
limit 最大允许上传个数 number
on-exceed 文件超出个数限制时的钩子 function(files, fileList)

element-ui上传代码实现

DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>title>
	head>
	<link rel="stylesheet" href="//unpkg.com/element-plus/lib/theme-chalk/index.css">
	<style>
		.text {
		    font-size: 14px;
		  }
		  .item {
		    padding: 18px 0;
		  }
		  .box-card {
		    width: 480px;
		  }
	style>
	<body>
		<div id="firmwareUpdate">
			<el-divider>el-divider>
			el-descriptions>
			<el-card class="box-card">
				<div :key="o" class="text item">
					<el-upload class="upload-demo" ref="upload" :on-preview="handlePreview" :on-remove="handleRemove" :on-change="handleChange"
					 :file-list="fileList" :auto-upload="false" :limit="1" :http-request="updateUpload">
						<template #trigger>
							<el-button size="small" type="primary">选取文件el-button>
						template>
						<el-button style="margin-left: 10px;" size="small" type="success" @click="updateUpload">上传到服务器el-button>
						<template #tip>
							<div class="el-upload__tip">
								只能上传一个文件,请不要瞎传!
							div>
						template>

					el-upload>
					<p id="data">p>
				div>
			el-card>
		div>
	body>
	<script src="//unpkg.com/vue@next">script>
	<script src="//unpkg.com/element-plus/lib/index.full.js">script>
	<script src="https://code.jquery.com/jquery-3.1.1.min.js">script>
	<script src="spark-md5.min.js">script>
	<script>
		var Main = {
			data() {
				return {
					//文件集合
					fileList: []
				};
			},
			methods: {
				updateUpload() {
					//获取文件file对象
					let file = this.$refs.upload.uploadFiles.pop().raw;
					//构造一个FileReader对象
					let reader = new FileReader();
					//readAsDataURL 方法会读取指定的 Blob 或 File 对象。读取操作完成的时候,	readyState 会变成已完成DONE,并触发 loadend (en-US) 事件,同时 result 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。
					reader.readAsDataURL(file);
					reader.onload = function(e) {
						var result = this.result;
						//文件的base64编码字符
						var base64 = this.result.substring(this.result.indexOf(',') + 1);
						//计算文件的md5值
						var md5Value = SparkMD5.hashBinary(e.target.result);
						$.ajax({
							headers: {
								Accept: "application/json; charset=utf-8"
							},
							url: url,
							type: 'post',
							async: false, //false 同步  true 异步 
							cache: false, //cache作用:是否在缓存中读取数据的读取。cache属性是true(默认值)时:在第一次请求完成之后,如果地址和参数不变化,第二次去请求,会默认获取缓存中的数据,不去读取服务器端的最新数据。cache属性是flase(默认值)时:每次读取的是最新的数据。
							timeout: 10000, //超时时间设置为10秒;
							dataType: 'json',
							data: {
								base64: base64,
								md5Value: md5Value,
							},
							success: function(data) {
								var msg = data.subCode;
								if (msg == 0) {
									alert("上传成功!");
								} else {
									alert("上传失败!");
								}
							},
							error: function(data) {
								alert("上传失败!");
							}
					});
					}
				},
				//删除触发
				handleRemove(file, fileList) {
					console.log(file, fileList);
				},
				//预览触发
				handlePreview(file) {
					console.log(file);
				},
				//发生改变触发
				handleChange(file, fileList) {
					console.log(file, fileList);
				},
			}
		};
		const app = Vue.createApp(Main);
		app.use(ElementPlus);
		app.mount("#firmwareUpdate")
	script>
html>

文章仅用作记录分享,若有不当,还望指正。

最近开通个人了微信公众号,以后将会定期分享工作学习过程中遇到的问题,欢迎关注与我一道成长交流~:

微信搜索: MYY668999程序猿爱篮球 即可上车。

你可能感兴趣的:(前端,vue,javascript,elementui,html,前端)