目录
上传
下载
get
post
对象/文件流
download处理返回
文件流
axios.post
封装axios
后端直接返回文件流,打开下载文件是 [object Object],将res改成res.data即可
1.请求设置类型responseType: 'blob'(如果没有设置,打开文件会是乱码)
2.若有请求拦截(直接返回即可)
3.download
4.请求下载
相关基础
Response.text()以Promise对象获取响应的文本数据
decodeURIComponent() 解码
escape() 编码
blob
MIME
get和post请求
缓存
副作用操作、获取/展示信息操作
Content-Disposition
CORS(Cross-Origin Resource Sharing) 跨域资源共享
要求
preflight预检查
请求分类
简单请求Simple Request(不会preflight)
应用
当服务端没有设置跨域时,可以将json伪装成text/plain
上传
submitAddFile(){
var formData = new FormData();
formData.append('num', this.addType);
formData.append('linkId',this.addId);
formData.append('rfilename',this.addFileName);
for(var i=0;i<this.addArr.length;i++){
formData.append('fileUpload',this.addArr[i]);
}
let config = {
headers: {
'Content-Type': 'multipart/form-data',
'Authorization': this.token
}
};
this.axios.post(apidate.uploadEnclosure,formData,config)
.then((response) => {
if(response.data.info=="success"){this.$message({
type: 'success',
message: '附件上传成功!'
});
}
})
}
vue 实现文件上传、下载的方法 - 掘金
下载
get
//静态a标签
<a :href='"/user/downloadExcel"' >下载模板</a>
//动态创建a标签:
<div name="downloadfile" onclick="downloadExcel()">下载</div>
function downloadExcel() {
let a = document.createElement('a')
a.href ="/user/downloadExcel"
a.click();
}
//window
function downloadExcel() {
window.location.href = "/tUserHyRights/downloadUsersUrl";
}
post
对象/文件流
download处理返回
import axios, { AxiosRequestConfig, AxiosResponse } from 'axios';
export const download= (response: { data?: any; config?: AxiosRequestConfig }) => {
console.log("response", response);
return new Promise((resolve, reject) => {
const fileReader = new FileReader();
fileReader.onload = function () {
try {
console.log("result:", this.result);
const jsonData = JSON.parse((this as any).result); // 成功 说明是普通对象数据
if (jsonData?.code !== 200) {
errorMsgTips(jsonData?.message ?? "请求失败");
reject(jsonData);
}
} catch (err) {
// 解析成对象失败,说明是正常的文件流
// responseType为blob,以便接收二进制数据。
const blob = new Blob([response.data]);
// 本地保存文件
const url = window.URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
const filename = response?.config.headers?.["content-disposition"]
?.split("filename*=")?.[1]
?.substr(7);
link.setAttribute("download", decodeURI(filename));
document.body.appendChild(link);
link.click();
resolve(response.data);
}
};
fileReader.readAsText(response.data);
});
文件流
axios.post
// Vue组件中的方法
methods: {
downloadFile() {
axios.post('/api/download', { /* 请求参数 */ }, { responseType: 'blob' })
.then(response => {
const url = window.URL.createObjectURL(new Blob([response.data]));
const link = document.createElement('a');
link.style.display = 'none'
link.href = url;
const filename = response?.config.headers?.["content-disposition"]
?.split("filename*=")?.[1]
?.substr(7);
link.setAttribute("download", decodeURI(filename));// 指定下载后的文件名,防跳转
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
})
.catch(error => {
// 处理错误
console.error(error);
});
}
}
从响应头中提取文件名:响应头的Content-Disposition
字段的值具有形式类似于filename*=UTF-8''example-file.txt
,并提取出文件名example-file.txt
。
封装axios
后端直接返回文件流,打开下载文件是 [object Object],将res改成res.data即可
1.请求设置类型responseType: 'blob'(如果没有设置,打开文件会是乱码)
import request from '@/utils/request'
import { AxiosRequestConfig, AxiosResponse } from 'axios'
const baseUrl: string = process.env.NODE_ENV === 'development' ? '/test' : ''
const mock: boolean = false
export const postQuery = (params: string): Promise<AxiosResponse> => {
const url: string = mock ? `${baseUrl}/xxx:8081/otherIndexUpload/${params}` : `${baseUrl}/otherIndexUpload/${params}`
console.log('post: ', url)
return request({ url, method: 'post', responseType: 'blob' })
}
return request({
url: '/data/wos/download',
method: 'post',
data: data,
responseType: 'blob',
timeout: 3000000,
onDownloadProgress: function (progressEvent: ProgressEvent<EventTarget>): void {
// 处理原生进度事件
store.state.percent = ((progressEvent.loaded / progressEvent.total) * 100).toFixed(2)
console.log(`下载进度:${store.state.percent}`)
if (Number(store.state.percent) == 100) {
store.commit('changeProgress')
}
}
})
2.若有请求拦截(直接返回即可)
import service from 'axios'
import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from 'axios';
// 响应拦截器
service.interceptors.response.use(
(response: { data: any; config: AxiosRequestConfig }) => {
const resData = response.data || {}
if (response.config.responseType === 'blob') {
return response
}..
},
(error: AxiosError) => {
...
}
)
export default service
3.download
export const download = (res: AxiosResponse) => {
var blob = new Blob([res.data], {
type: "application/vnd.ms-excel;charset=utf-8",
});
var url = window.URL.createObjectURL(blob);
var aLink = document.createElement("a");
aLink.style.display = "none";
//指定文件名,防止跳转
aLink.download =decodeURIComponent(escape(res?.headers?.["content-disposition"]?.split("filename=")?.[1]))
aLink.href = url;
document.body.appendChild(aLink);
aLink.click();
document.body.removeChild(aLink);
}
4.请求下载
toDownloadTemplate() {
console.log('下载模板')
API.postQuery(`downloadTemplate/${this.wpReleId}`).then((res: any) => {
if (res.data.type === "application/vnd.ms-excel") {
download(res);
} else {
res.data.text().then((res: any) => {
this.$message.warning(JSON.parse(res).msg)
})
}
})
}
相关基础
Response.text()以Promise对象获取响应的文本数据
适用于requst指定responseType后,但响应的content-type有的不适合该responseType
fetch('https://example.com/api/data')
.then(response => response.text())
.then(textData => {
console.log(textData); // 输出响应的文本数据
})
.catch(error => {
console.error(error);
});
decodeURIComponent()
解码
函数对编码后的字符串进行解码,显示正常内容
escape()
编码
函数对乱码字符串进行编码,以确保特殊字符(如中文)按照 UTF-8 进行编码。
blob
二进制大对象(Binary Large Object)。Blob是存储二进制数据的数据类型,例如图像、音频和视频文件等
MIME
多用途互联网邮件扩展(Multipurpose Internet Mail Extensions)表示传输的文件的性质和格式。在HTTP头部或其他协议中指定一个特定的字符串,来标识文件的类型。
主类型表示文件的大类别,
"application"表示应用程序类型,
"text"表示文本类型,
"image"表示图像类型等。
子类型表示具体的文件格式,
"plain"表示纯文本,
"vnd"表示自定义类型
"vnd.ms-excel":Microsoft Excel电子表格文件。
get和post请求
POST:用于传输信息给服务器,功能与 GET 类似,但一般推荐使用 POST 方式;
GET: 用于请求访问已经被 URI(统一资源标识符)识别的资源,可以通过 URL 传参给服务器;
对于GET方式的请求,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
对于POST,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)。
在网络环境好的情况下,发一次包的时间和发两次包的时间差别基本可以无视。
在网络环境差的情况下,两次包的TCP在验证数据包完整性上,有非常大的优点。
因为GET一般用于查询信息,POST一般用于提交某种信息进行某些修改操作(私密性的信息如注册、登陆)
所以GET在浏览器回退不会再次请求,POST会再次提交请求
因为GET在浏览器回退不会再次请求,POST会再次提交请求
所以GET请求会被浏览器主动缓存,POST不会,要手动设置
GET请求参数会被完整保留在浏览器历史记录里,POST中的参数不会
因为 GET请求参数会被完整保留在浏览器历史记录里
所以GET请求在URL中传送的参数是有长度限制的,而POST没有限制
因为GET参数通过URL传递,POST放在Request body中
所以超链接下载是get请求
缓存
副作用操作、获取/展示信息操作
文件下载是一种副作用操作,而不是用于获取资源的常规GET请求。
浏览器通常认为文件下载的响应是一次性的,不会重复使用,
所以即便是会默认缓存的get请求也不会将其存储在缓存中。
即使浏览器选择将文件内容存储在缓存中,它通常会将其存储在临时缓存sessionStorage中,而不是长期持久的缓存
localStorage
中。
请求返回的文件保存在浏览器缓存后,再用href下载,即get请求从缓存总搬运到目的路径一次。
因为GET在浏览器回退 不会再次请求,POST会再次提交请求
所以GET请求会被浏览器主动缓存,以便再次请求
GET请求参数会被完整保留在浏览器历史记录里,POST中的参数不会
max-age单位:秒
因为POST请求由于其具有副作用(例如修改服务器上的数据),
所以浏览器通常不会缓存POST响应结果,要手动设置缓存(Cache-Control,Expires、Last-Modified,Content-Disposition)
Content-Disposition
-
attachment
: 表示将内容作为附件下载。 -
inline
: 表示将内容内嵌到页面中,通常用于直接显示非 HTML 内容,如 PDF、图像等。 -
form-data
: 表示响应内容是一个表单数据,通常用于表单上传文件的情况。
Content-Disposition: attachment; filename="example.pdf"
attachment
表示将响应内容作为附件下载,
filename="example.pdf"
指定了保存文件时的文件名为"example.pdf"
浏览器可能会在内存中临时存储一部分文件数据,以便在写入目标路径时进行处理。
然而,这不是浏览器缓存的一部分,而是用于文件传输和写入的临时存储。
CORS(Cross-Origin Resource Sharing) 跨域资源共享
允许浏览器向跨源服务器发送XMLHttpRequest
请求,从而克服了 AJAX 只能同源使用的限制
属于跨源 AJAX 请求的根本解决方法,最常用的一种解决办法
要求
目前,所有浏览器都支持该功能,IE浏览器不能低于IE10
CORS 需要浏览器和后端同时支持。IE 8 和 9 需要通过 XDomainRequest 来实现。
服务端设置 Access-Control-Allow-Origin 就可以开启 CORS。 该属性表示哪些域名可以访问资源,如果设置通配符则表示所有网站都可以访问资源。
preflight预检查
预检请求是指浏览器在发送跨域请求之前,会先发送一个 OPTIONS 请求,用于询问服务器是否接受实际的请求。
预检请求主要用于对复杂请求(例如包含自定义请求头或使用非简单标头字段的请求)进行安全验证。
请求分类
CORS分为简单请求,非简单/复杂请求
简单请求Simple Request(不会preflight)
只要同时满足以下两大条件,就属于简单请求
条件1:使用下列方法之一:
- GET
- HEAD
- POST
条件2:除了被允许的自定义请求头(例如:X-PINGOTHER),请求头仅包含一些简单标头字段,如:Accept、Accept-Language、Content-Language、Content-Type,Range。
其中Content-Type 的值仅限于下列三者之一:
- text/plain
- multipart/form-data(键值对型数据)
- application/x-www-form-urlencoded(URL encoded)(默认)
application/xml 、 text/xml、text/html、text/plain的区别
1、text/html是html格式的正文
2、text/plain是无格式正文(可以有效避免XSS漏洞)
3、text/xml忽略xml头所指定编码格式而默认采用us-ascii编码
4、application/xml会根据xml头指定的编码格式来编码:
请求中的任意 XMLHttpRequestUpload 对象均没有注册任何事件监听器;
XMLHttpRequestUpload 对象可以使用 XMLHttpRequest.upload 属性访问。
GET /cors? HTTP/1.1
Host: localhost:2333
Connection: keep-alive
Origin: http://localhost:2332
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.98 Safari/537.36
Accept: */*
Referer: http://localhost:2332/CORS.html
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
If-None-Match: W/"1-NWoZK3kTsExUV00Ywo1G5jlUKKs"
只需服务器端设置Access-Control-Allow-Origin(表示接受那些域名的请求(*为所有))
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
Access-Control-Allow-Methods:指定允许的HTTP方法。例如,
Access-Control-Allow-Methods: GET, POST, PUT
表示允许GET、POST和PUT方法。Access-Control-Allow-Headers:指定允许的HTTP头字段。例如,
Access-Control-Allow-Headers: Content-Type, Authorization
表示允许Content-Type和Authorization字段。Access-Control-Max-Age:指定预检请求(OPTIONS请求)的缓存时间,以避免频繁发送预检请求。
Access-Control-Allow-Credentials:指示是否允许发送身份凭证(如cookies)到目标域。如果设置为true,则表示允许发送。
Access-Control-Expose-Headers 是一个CORS(跨源资源共享)响应头字段,用于指定在跨域请求中可以访问的额外响应头字段。
Access-Control-Expose-Headers,服务器可以指定额外的响应头字段,这些字段将被浏览器放行并允许 JavaScript 代码访问。
当浏览器发起跨域请求时,由于安全原因,只有一些默认的响应头字段(如Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma)可以被访问。其他自定义的响应头字段,默认情况下是不可访问的。
应用
当服务端没有设置跨域时,可以将json伪装成text/plain
原理:
包装成简单请求,以躲过预检查。但是有些客户端或者代理还是会预检查
安全:
浏览器对于 JSON 响应的默认处理机制是自动将其解析为 JavaScript 对象。
当浏览器接收到响应时,如果响应的 Content-Type 是 application/json 或没有指定 Content-Type,浏览器会自动将响应体解析为 JSON, JavaScript 对象,如果是恶意代码可能会被执行,导致安全漏洞或攻击。
通过将 JSON 响应伪装成 text/plain 类型,可以避免浏览器将响应自动解析为 JavaScript 对象的默认行为。
这样一来,JavaScript 代码需要手动对响应进行解析,确保数据的安全性和正确性。这种伪装可以提供额外的安全层,防止对于响应的自动解析可能带来的安全风险。
//请求头
GET /example HTTP/1.1
Host: example.com
Accept: text/plain
//响应头
HTTP/1.1 200 OK
Content-Type: text/plain
//响应体
{"foo": "bar"}
跨源资源共享(CORS) - HTTP | MDN文章来源:https://www.toymoban.com/news/detail-566028.html
Cross-Origin Resource Sharing (CORS) - HTTP | MDN文章来源地址https://www.toymoban.com/news/detail-566028.html
到了这里,关于vue upload 下载的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!