http mime type
content-type 支撑的 media types:www.iana.org/assignments…
后端发给的 mime type
后端一顿操作后,设置一堆呼应头
然后咱们去调用接口,假如需要下载的话,后端会调用流输出方法
response.getOutputStream()
axios responseType 类型的设置
responseType 表明浏览器将要呼应的数据类型
其间 blob,arraybuffer 用于 excel,pdf 这种数据流文件下载
打不开文件相关问题
后端回来数据流 excel,pdf 下载之后,打不开问题
- 有或许是编码不对
- 接口没加上 responseType 呼应类型,指定浏览器呼应的类型
- 本地敞开了mockjs,相应类型也或许会受到影响,mockjs会影响原生的 ajax 请求,使得服务器回来的 blob/arraybuffer 类型的变成乱码
// 1. 处理回来数据流下载进程编码不对
export const useDownloadFile = (data: Blob, fileName: string, format: string) => {
let name!: string
let type = ''
if (format === 'pdf') {
// 这儿的 type 类型要与 接口呼应头的 content-type 保持一致
type = 'application/pdf;chartset=utf-8'
name = `${fileName}.pdf`
}
if (format === 'excel') {
// 这儿的 type 类型要与 接口呼应头的 content-type 不一致,短少 utf-8 编码
type = 'application/vnd.ms-excel;'
name = `${fileName}.xlsx`
}
const blob = new Blob([data], { type: type })
/**省略下载处理进程**/
}
// 2. 第二种状况,接口没加呼应类型
export const $DownloadPartList = (params: IDownloadPartListParams): Promise<Blob> => {
return $axios.post(`xxxx`, params)
}
// 3. 或许本地敞开了 mockjs,会有影响,暂时没用
这三种状况都有或许导致下载的 excel,pdf打不开
正确是方法:
// 1. 处理回来数据流下载进程 type 类型要与 接口呼应头的 content-type 保持一致
export const useDownloadFile = (data: Blob, fileName: string, format: string) => {
let name!: string
let type = ''
if (format === 'pdf') {
// 这儿的 type 类型要与 接口呼应头的 content-type 保持一致
type = 'application/pdf;chartset=utf-8'
name = `${fileName}.pdf`
}
if (format === 'excel') {
// 这儿的 type 类型要与 接口呼应头的 content-type 保持一致
type = 'application/vnd.ms-excel;chartset=utf-8'
name = `${fileName}.xlsx`
}
const blob = new Blob([data], { type: type })
/**省略下载处理进程**/
}
// 2. 第二种状况,接口加呼应类型
export const $DownloadPartList = (params: IDownloadPartListParams): Promise<Blob> => {
return $axios.post(`xxx`, { ...params }, { responseType: 'arraybuffer' })
}
// 3. 关闭 mockjs
不得不说 content-type 和 content-disposition,X-Content-Type-Option
-
content-type
:在呼应中,Content-Type
标头告诉客户端实际回来的内容的内容类型。 浏览器会在某些状况下进行MIME
查找,并不一定遵从此标题的值;
// pdf
content-type: application/pdf;chartset=utf-8
// excel
content-type: application/vnd.ms-excel;charset=utf-8
// json
content-type: application/json
// multipart form data boundary 表明分隔符,这种能够分段传输
content-Type: multipart/form-data; boundary=----WebKitFormBoundaryVHUV1SACt6dkGtj9
-
x-content-type-option
:为了避免不遵从content-type
,能够将标题X-Content-Type-Options
设置为nosniff
。这个便是跟excel
,pdf下载的时候出现打不开的状况息息相关,表明前端处理数据流下载的类型要跟content-type
一致 -
content-disposition
:当文件支撑下载的状况,就会设置这个字段,其间attachment
表明支撑下载
Content-Disposition: inline // 直接在页面打开
Content-Disposition: attachment // 支撑下载
Content-Disposition: attachment; filename="filename.jpg"
// form-data方法
Content-Disposition: form-data
Content-Disposition: form-data; name="fieldName"
Content-Disposition: form-data; name="fieldName"; filename="filename.jpg"
回到上面下载 excel
,pdf
的例子
content-type
为 multipart/form-data; boundary=***
的状况
浏览器识别到这种 form-data
格局的接口,会主动设置 multipart/form-data; boundary=----WebKitFormBoundaryyUZoKpRYHZjSBBTP
看这篇文章的解析:/post/697106…
浏览器会解析成这样
- 开始分隔符:
------multipart/form-data; boundary=----WebKitFormBoundaryyUZoKpRYHZjSBBT
- 字段:
Content-Disposition: form-data; name="billno"
- 空行
- 再是对应的值:
FBBJD20221219401263
- 结束分隔符:
------multipart/form-data; boundary=----WebKitFormBoundaryyUZoKpRYHZjSBBT
和--
前端API处理流
- 不可变二进制字节省:blob
- 针对文件字节省blob不可变晋级版别:fileReader 像上传图片,前端图片预览
- 可变二进制字节省:arraybuffer
呼应类型是 arraybuffer 有两种处理方法
- 一种是直接运用
blob
对象处理 - 另一种便是先写入
arraybuffer
缓冲区,然后操作 arraybuffer - 一般都是挑选第一种方法
参考链接:blog.csdn.net/weixin_4329…
更多 arraybuffer, fileReader, 其他对象运用,后边运用到再弥补
// 将回来的数据用数组包起来,为 `Blob` 对象创立一个 类型化数组,然后运用 `URL.createObjectURL(blob)` 转成一个链接进行下载
// 这儿的 `type` 也是对应 `content-type` 里边的 `mime type` 类型
export const useDownloadFile = (data: Blob, fileName: string, format: string) => {
let name!: string
let type = ''
if (format === 'pdf') {
type = 'application/pdf;chartset=utf-8'
name = `${fileName}.pdf`
}
if (format === 'excel') {
type = 'application/vnd.ms-excel;charset=utf-8'
name = `${fileName}.xlsx`
}
// [data] 为 Blob 对象创立一个 类型化数组,这儿的 type 与 content-type 保持一致
const blob = new Blob([data], { type: type })
if ('download' in document.createElement('a')) {
// 非IE下载
const elink = document.createElement('a')
elink.download = name
elink.style.display = 'none'
elink.href = URL.createObjectURL(blob)
document.body.appendChild(elink)
elink.click()
URL.revokeObjectURL(elink.href)
document.body.removeChild(elink)
} else {
try {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
;(window.navigator as any).msSaveBlob(blob, name)
} catch (e) {
console.log(e)
}
}
}
http 安全
-
X-Content-Type-Options:音讯头相当于一个提示标志,被服务器用来提示客户端一定要遵从在
Content-Type
首部中对 MIME 类型 的设定,而不能对其进行修改 -
X-Frame-Options:假如设置为
DENY
,不光在别人的网站 frame 嵌入时会无法加载,在同域名页面中同样会无法加载。另一方面,假如设置为SAMEORIGIN
,那么页面就能够在同域名页面的 frame 中嵌套。 -
X-XSS-Protection:
X-XSS-Protection: 0 制止 XSS 过滤。 X-XSS-Protection: 1 启用 XSS 过滤(通常浏览器是默认的)。假如检测到跨站脚本进犯,浏览器将铲除页面(删去不安全的部分)。 X-XSS-Protection: 1; mode=block 启用 XSS 过滤。假如检测到进犯,浏览器将不会铲除页面,而是阻挠页面加载。 X-XSS-Protection: 1; report=<reporting-uri> 启用 XSS 过滤。假如检测到跨站脚本进犯,浏览器将铲除页面并运用 CSP report-uri (en-US)指令的功用发送违规报告。