js 通过 form-data 的形式实现自定义文件上传和下载

element-ui 中不使用它的上传控件,利用原生 input 标签,隐藏其默认样式,采用自定义的方式上传:

<el-form-item label="文件上传和下载">
	<el-input v-model="fileUrl" readonly></el-input>
	<input type="file" id="file" accept="" @change="handleFileChange" />
	<label class="el-button el-button--small" for="file"></label>
	<el-button size="small" type="primary" @click="handleUpload">上传</el-button>
	<el-button size="small" type="primary" @click="handleDownload">下载</el-button>
</el-form-item>

import { uploadFile, downloadFile } from '@/api'
import { saveAs } from '@/utils'
export default {
	data() {
		return {
			fileUrl: '',
			file: null
		}
	},
	methods: {
		handleFileChange(e) {
			this.file = e.target.files[0]
			this.fileUrl = this.file.name
		}
		async handleUpload() {
			let name = 'image'
			let filename = 'test.png'
			await uploadFile(name, filename, this.file)
		}
		async handleDownload() {
			let type = 'image'
			let name = 'test.png'
			const res = await downloadFile(type, name)
			saveAs(res, 'download.png')
		}
	}
}

文件上传与后端约定 namefilenamefile 字段,其中 file 为文件流

// @/api/index.js
// 文件上传
export function uploadFile(name, filename, file) {
	let formData = new FormData()
	formData.append('name', name)
	formData.append('filename', filename)
	return $axios({
		url: '/upload',
		method: 'post',
		data: formData,
		headers: {
			'Content-Type': 'application/x-www-form-urlencoded'
		}
	})
}

文件下载服务端会返回文件流,约定 typename 字段,设置相应类型 responseType: 'arraybuffer',设置响应头 Content-Type: 'application/octet-stream',告知浏览器这是一个字节流,浏览器处理字节流的默认方式就是下载

// @/api/index.js
// 文件下载
export function downloadFile(type, name) {
	let formData = new FormData()
	formData.append('type', type)
	formData.append('name', name)
	return $axios({
		url: '/download',
		method: 'post',
		data: formData,
		responseType: 'arraybuffer',
		headers: {
			'Content-Type': 'application/octet-stream'
		}
	})
}

文件下载需要获取服务传输的文件流,创建浏览器下载链接保存文件:

// @/utils/index.js
export const saveAs(buffers, name, mine = 'application/octet-stream') => {
	const blob = new Blob([buffers], { type: mime })
	const url = window.URL.createObjectURL(blob)
	const link = document.createElement('a')
	link.href = url
	link.setAttribute('download', name)
	document.body.appendChild(link)
	link.click()
	document.body.removeChild(link)
	window.URL.revokeObjectURL(url)
}

$axios 方法是二次封装的 axios 实例:

// request.js
import axios from 'axios'
const baseURL = ''
const instance = axios.create({
	baseURL,
	timeout: 3000
})
export default instance
  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值