记录-文件上传和下载-小坑
- 文件下载
- 坑
- 通用封装
- 文件上传
- 坑
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 = url
dom.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' } = obj
const blob = new Blob([data], { type: headerType })
const url = window.URL.createObjectURL(blob)
const dom = document.createElement('a')
dom.href = url
dom.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 + 文件标识
```javascript
import 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.data
console.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', // 不传cookie
headers: {
'Token': xxx,
'System-Host': xx
},
method: 'POST' // *GET, POST, PUT, DELETE, etc.
})
res = await res.json()
console.log(res)
}