记录-文件上传和下载-小坑
- 文件下载
- 坑
- 通用封装
- 文件上传
- 坑
1. 文件下载
- 针对url(http://xxxxxx/a.zip) 的下载
- window.open(
url, ‘_self’) // 是能下载的链接,就直接下载
- window.open(
// 以下代码可以控制台直接跑起来var data = ['<a id="a"><b id="b">hey!</b></a>']; // data,用数组包裹var blob = new Blob(data, {type : 'application/octet-stream;charset=utf-8'}); // 生成Blob对象, Blob对象表示一个不可变、原始数据的类文件对象var url = window.URL.createObjectURL(blob) // 生成一个url:可以指向 File 对象或 Blob 对象。window.open(url) // 打开url,如果是下载链接则下载
针对文件流的下载
接口给到一个文件流的话,其实也可以和上面的方法一样去下载。但是缺点是需要用户自己去手动输入 下载的文件名和格式,否则是没有后缀的文件,会显示打不开
以下我们用dom的download属性下载const downFile = (data, filename = '模板.xlsx', headerType = 'application/octet-stream;charset=utf-8') => {const blob = new Blob([data], { type: headerType }) // 生成Blob对象, Blob对象表示一个不可变、原始数据的类文件对象const url = window.URL.createObjectURL(blob) // 生成一个url:可以指向 File 对象或 Blob 对象。const dom = document.createElement('a')dom.href = urldom.download = decodeURI(filename) // 用dom的download下载,可以设置默认文件名dom.style.display = 'none'document.body.appendChild(dom)dom.click()dom.parentNode.removeChild(dom) // 释放内存window.URL.revokeObjectURL(url) // 释放内存}
!!!此处有个坑,需要特别注意:
文件流是从接口拿的,请求的axios需要配置 responseType !!!
```javascript export const get_xxx = (params) => { return axios({ method: ‘get’, url: “/xxxx”, responseType: “blob”, // 拿文件流需要配置这个 params }) }
// axios 内:
// responseType 表示服务器响应的数据类型,
// 可以是 ‘arraybuffer’, ‘blob’, ‘document’, ‘json’, ‘text’, ‘stream’
responseType: ‘json’, // 默认的
3. 最终封装```javascript/*** 方法说明 下载文件, 有2种形式, 1. url (例如: http://xxxxx/a.zip) 2. 文件流, 且需要默认文件名* @method downFile* @param{object} url data filename headerType** 使用示例:* 形式1: downFile({ url: 'http://xxxxx/a.zip' })* 形式2: downFile({* data: 'xxx文件流',* filename: '模板.xlsx', // 可选, 默认'模板.xlsx'* headerType: 'application/octet-stream;charset=utf-8', // 可选 默认'application/octet-stream;charset=utf-8'* })*/export const downFile = function (obj) {if (obj.url) { // 形式1 url (例如: http://xxxxx/a.zip)window.open(url)} else { // 形式2 文件流, 且需要默认文件名const { data, filename = '模板.xlsx', headerType = 'application/octet-stream;charset=utf-8' } = objconst blob = new Blob([data], { type: headerType })const url = window.URL.createObjectURL(blob)const dom = document.createElement('a')dom.href = urldom.download = decodeURI(filename) // 用dom的download下载,可以设置默认文件名dom.style.display = 'none'document.body.appendChild(dom)dom.click()dom.parentNode.removeChild(dom) // 释放内存window.URL.revokeObjectURL(url) // 释放内存}}
2. 文件上传
先说一下小坑,憋着难受 ( ̄. ̄||)
如果响应头: Access-Control-Allow-Origin: *白名单直接配置了*的话,前端就不能带cookie !!!!否则接口会报跨域的错误
接下来继续讲文件上传
- 用ui组件 (此处用的iview)
然后,如果接口需要加参数,则加个 name=”excelFile”
```html点击或拖拽上传文件
注意点:公司内部平台,一般来说,都需要设置请求头 不要加Content-Type: multipart/form-data; ( 文件上传默认会自动适配Content-Type, 千万不要在额外加 ) 其他的请求头需要多少,就自行加上 此处有个坑点 ui组件配置 with-credentials(支持发送 cookie 凭证信息, 默认false,如果要改为true 要小心),这个坑点就是上面写的
2. 自己写上传1. 用axios上传<br />最好,重新引入axios,因为,项目内的axios可能被封装过,Content-Type 可能已经被动过了,要文件上传能够成功,这个Content-Type不能动,他会自动识别到是文件上传multipart/form-data + 文件标识```javascriptimport Axios from 'axios'const upload = (file) => {// file 是 File对象const formData = new FormData()formData.append('excelFile', file) // 接口需要传参excelFile,具体情况具体分析let res = await Axios.post('http://xxxx/import', formData, {headers: {'Token': xxx,'System-Host': xx}})res = res.dataconsole.log(res)}
- 用fetch上传
const upload = (file) => {// file是 File 对象const formData = new FormData()formData.append('excelFile', file) // 接口需要传参excelFile,具体情况具体分析let res = await fetch('http://xxxxx/import', {body: formData,credentials: 'omit', // 不传cookieheaders: {'Token': xxx,'System-Host': xx},method: 'POST' // *GET, POST, PUT, DELETE, etc.})res = await res.json()console.log(res)}
