http mime type

content-type 支撑的 media types:www.iana.org/assignments…

后端发给的 mime type

文件流处理相关常识收拾
后端一顿操作后,设置一堆呼应头

文件流处理相关常识收拾

然后咱们去调用接口,假如需要下载的话,后端会调用流输出方法

response.getOutputStream()

axios responseType 类型的设置

responseType 表明浏览器将要呼应的数据类型

文件流处理相关常识收拾

其间 blob,arraybuffer 用于 excel,pdf 这种数据流文件下载

打不开文件相关问题

后端回来数据流 excel,pdf 下载之后,打不开问题

  1. 有或许是编码不对
  2. 接口没加上 responseType 呼应类型,指定浏览器呼应的类型
  3. 本地敞开了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打不开

image-20221221153237238

文件流处理相关常识收拾
正确是方法:

// 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"

回到上面下载 excelpdf 的例子

文件流处理相关常识收拾
content-typemultipart/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)指令的功用发送违规报告。