①以base64字符串上传(使用FileReader对象获取文件的base64字符串)
FileReader参考文档: FileReader - Web API 接口参考 | MDN
FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 File 或 Blob 对象指定要读取的文件或数据。
FileReader:
- ref="upload"
- type="file"
- accept="image/*,application/pdf"
- @change="uploadFile($event.target.files)"
- style="display: none;" />
- <div @click="$ref.upload.click()" class="m-upload">选择文件div>
- <div @click="$refs.upload.click()" ref="dragUpload" class="m-upload">
- <img src="@/assets/images/add-upload.svg" class="u-upload" />
- <div class="assist">div>
- div>
-
- mounted () {
- // 将ref为dragUpload的元素变成drop区域
- this.$refs.dragUpload.addEventListener('dragenter', this.dragenter, false)
- this.$refs.dragUpload.addEventListener('dragover', this.dragover, false)
- this.$refs.dragUpload.addEventListener('drop', this.drop, false)
- },
- methods: {
- dragenter (e) {
- e.stopPropagation()
- e.preventDefault()
- this.$once('hook:beforeDestroy', function () {
- removeEventListener('dragenter', this.dragenter)
- })
- },
- dragover (e) {
- e.stopPropagation()
- e.preventDefault()
- this.$once('hook:beforeDestroy', function () {
- removeEventListener('dragover', this.dragover)
- })
- },
- drop (e) { // 拖拽上传方法
- e.stopPropagation()
- e.preventDefault()
- const files = e.dataTransfer.files
- this.uploadFile(files)
- this.$once('hook:beforeDestroy', function () {
- removeEventListener('drop', this.drop)
- })
- },
- uploadFile (files) { // 统一上传文件方法
- console.log('开始上传 upload-event files:', files)
- if (files.length) {
- var reader = new FileReader()
- // reader.readAsBinaryString(files[0])
- reader.readAsDataURL(files[0]) // 以base64方式读取文件内容
- reader.onloadstart = function (e) { // 当读取操作开始时触发
- const fileSize = e.total
- if (fileSize > 1024 * 500) { // 大于500KB时取消上传
- reader.abort()
- } else {
- console.log('开始读取 onloadstart:', e)
- }
- }
- reader.onabort = function (e) { // 当读取操作被中断时触发
- console.log('读取中止 onabort:', e)
- }
- reader.onerror = function (e) { // 当读取操作发生错误时触发
- console.log('读取错误 onerror:', e)
- }
- reader.onprogress = function (e) { // 在读取Blob时触发,读取上传进度,50ms左右调用一次
- console.log('读取中 onprogress:', e)
- console.log('已读取:', Math.ceil(e.loaded / e.total * 100) + '%')
- }
- const that = this
- reader.onload = function (e) { // 当读取操作成功完成时调用
- console.log('读取成功 onload:', e)
- // 该文件的base64数据,前端可直接用来展示图片
- // that.preImg = e.target.result
- // 若使用标签展示图片,可直接赋值src属性
- // document.getElementById('img').src = e.target.result
- // 调用上传接口,上传base64格式的文件数据
- const fileType = files[0].type.slice(files[0].type.indexOf('/') + 1)
- var formData = {
- uploadFile: e.target.result,
- fileFormat: fileType
- }
- console.log('提交数据:', formData)
- upload(formData).then(res => {
- console.log('upload-res:', res)
- if (res.message.code === 0) {
- that.fileUrl = res.data.url
- }
- }).finally(() => {
- // input的change事件默认保存上一次input的value值,同一value值(根据文件路径判断)在上传时不重新加载
- that.$refs.upload.value = ''
- })
- }
- reader.onloadend = function (e) { // 当读取操作结束时触发(要么成功,要么失败)触发
- console.log('读取结束 onloadend:', e)
- }
- }
- }
- }
- .m-upload { // 拖动区域元素
- position: relative;
- display: inline-block;
- width: 98px;
- height: 98px;
- background: #FFFFFF;
- border: 1px dashed #D1D1D1;
- text-align: center;
- cursor: pointer;
- .u-upload { // 垂直居中
- width: 20px;
- height: 20px;
- display: inline-block;
- vertical-align: middle;
- }
- .assist { // 垂直居中辅助元素
- height: 100%;
- width: 0;
- display: inline-block;
- vertical-align: middle;
- }
- }
②以二进制文件流上传(使用FormData模拟form表单提交)
FormData参考文档: FormData - Web API 接口参考 | MDN
FormData 接口提供了一种表示表单数据的键值对 key/value 的构造方式,并且可以轻松的将数据通过XMLHttpRequest.send() 方法发送出去,本接口和此方法都相当简单直接。如果送出时的编码类型被设为 "multipart/form-data",它会使用和表单一样的格式。
实现了 FormData 接口的对象可以直接在for...of结构中使用,而不需要调用entries() : for (var p of myFormData) 的作用和 for (var p of myFormData.entries()) 是相同的。
FormData方法:
- FormData.append():向 FormData 中添加新的属性值,FormData 对应的属性值存在也不会覆盖原值,而是新增一个值,如果属性不存在则新增一项属性值。
- FormData.delete():从 FormData 对象里面删除一个键值对。
- FormData.entries():返回一个包含所有键值对的iterator对象。
- FormData.get():返回在 FormData 对象中与给定键关联的第一个值。
- FormData.getAll():返回一个包含 FormData 对象中与给定键关联的所有值的数组。
- FormData.has():返回一个布尔值表明 FormData 对象是否包含某些键。
- FormData.keys():返回一个包含所有键的iterator对象。
- FormData.set():给 FormData 设置属性值,如果FormData 对应的属性值存在则覆盖原值,否则新增一项属性值。
- FormData.values():返回一个包含所有值的iterator对象。
- uploadFile (files) {
- console.log('开始上传 upload-event files:', files)
- if (files.length) {
- if (files[0].size > 500 * 1024) { // 校验文件大小
- this.content = '文件大小不能超过500KB'
- this.showTip = true
- } else {
- const fileType = files[0].type.slice(files[0].type.indexOf('/') + 1)
- var formData = new FormData()
- formData.set('uploadFile', files[0])
- formData.set('fileFormat', fileType)
- // 调用接口上传文件
- upload(formData).then(res => {
- console.log('upload-res:', res)
- if (res.message.code === 0) {
- this.fileUrl = res.data.url
- }
- }).finally(() => {
- this.$refs.upload.value = ''
- })
- }
- }
- }