文件下载相关请求头和响应头
// 请求头
Accept: 指定客户端接受的内容类型,如 Accept: application/octet-stream 表示接受二进制流文件。
Range: 请求部分内容,例如 Range: bytes=0-499 只请求文件的前500字节,适用于断点续传。
Accept-Encoding:指定客户端支持的内容编码方式,如压缩。例如:Accept-Encoding: gzip, deflate。
User-Agent:提供客户端软件的信息,通常用来识别浏览器类型。例如:User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36.
Referer:表示请求的来源页面。对于文件下载来说,可能会用来防止直接下载链接的滥用。例如:Referer: https://example.com/download.
Authorization:用于在下载文件时携带身份验证信息,如基于 Bearer 的 Token。例如:Authorization: Bearer <token>。
// 响应头
Content-Disposition: 告诉浏览器应该如何处理响应体中的内容,通常用来触发下载行为。例如: Content-Disposition: attachment; filename="example.pdf"
- inline:指示浏览器直接显示内容,通常用于显示图像、PDF 等可以在浏览器中渲染的文件。
- attachment:指示浏览器将文件作为附件下载,并且不在浏览器中直接显示。
Content-Type: 表示文件返回的媒体类型,如 Content-Type: application/pdf。
Content-Length: 文件的大小,以字节为单位。
Cache-Control:用于控制缓存行为。在文件下载的情况下,通常会使用以下设置:Cache-Control: no-cache, no-store, must-revalidate
- no-cache:指示浏览器不要缓存文件,每次下载时都从服务器获取最新的文件。
- private 或 no-store:防止文件被缓存或存储。
Expires:用于设置文件缓存的到期时间。通常与 Cache-Control 一起使用,用于指定缓存的有效期。对于下载文件,通常会设置为一个过去的时间来禁用缓存。
ETag:用于标识资源的唯一版本。当文件更新时,ETag 的值会变化,帮助浏览器判断文件是否发生了变化,从而决定是否重新下载文件。
Content-Range: 在分段下载时,显示响应的部分内容范围,例如 Content-Range: bytes 0-499/1234。
Accept-Ranges: 指示服务器支持断点续传,例如 Accept-Ranges: bytes。
一、location.href
对于一些浏览器无法识别的文件格式,可以直接再浏览器地址栏输入url即可触发浏览器的下载功能。对于单文件下载没有什么问题,但是如果下载多文件,点击过快就会重置掉前面的请求。
适用场景:
- get请求
- 单文件下载
window.location.href = url;
1、文件类型pdf等,浏览器直接输入链接即可下载,但有例外:
- 浏览器配置,如谷歌浏览器,谷歌浏览器设置》隐私和安全》网站设置》PDF文档,可设置访问链接时下载/预览文件
- 服务器的 【Content-Disposition】 头部决定了浏览器如何处理文件。假设希望文件在浏览器中打开,而不是下载,应该确保 【Content-Disposition】 头部设置为 【inline】,而不是 【attachment】:
`inline`:告诉浏览器在页面中直接显示 PDF 文件。
`attachment`:告诉浏览器下载文件,而不是直接显示。
Content-Disposition: inline; filename="document.pdf"
2、图片类型jpg等,浏览器直接输入链接,只能预览
3、其他网页网址,当前窗口跳转新页面
// pdf下载,当前页下载文件(取决于浏览器配置和服务器配置)
window.open("https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf")
// 图片预览,当前窗口预览
window.open("https://picsum.photos/200/300")
// 其他网页网址,当前窗口跳转新页面
window.open("https://www.runoob.com/jsref/met-win-open.html")
二、window.open
和location.href类似
window.open(url);
- pdf等文件类型,直接下载,不会打开新窗口
- 图片类型,打开新窗口预览
- 其他网页网址,打开新窗口跳转页面
// pdf下载,当前页下载文件
window.open("https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf")
// 图片预览,打开新窗口预览
window.open("https://picsum.photos/200/300")
// 其他网页网址,打开新窗口跳转页面
window.open("https://www.runoob.com/jsref/met-win-open.html")
三、a标签
与上面两种类型类似,图片类型会被直接预览,文件类型等根据浏览器/服务器配置预览或者下载,但a标签有个download属性可触发文件下载以及设置下载的文件名,但该属性只在文件与页面来源相同的情况下有效。
适用场景:
- get请求
- 单文件下载
- 需要自定义文件名
a标签下载相关属性:
download:
1、 当设置了 `download` 属性时,点击链接将触发文件下载,而不是直接在浏览器中打开文件。
2、你可以为下载的文件指定一个文件名。如果没有指定文件名,则会使用目标资源的默认文件名。
// 点击链接将触发文件下载,而不是直接在浏览器中打开文件
<a href="https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf" download>Download PDF</a>
// 指定文件名
<a href="https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf" download="被修改过的文件名">Download as New Name</a>
// 注意:
// 1、download 属性仅适用于同源的 URL,或者文件与页面来源相同的情况。跨域资源默认无法使用 download 属性,除非设置了相关的 CORS(跨源资源共享)策略。
// 2、该属性并不适用于所有文件类型,某些类型的文件可能仍然会在浏览器中打开(例如图片或文本文件)。
四、Blob对象(结合URL.createObjectURL和URL.revokeObjectURL实现文件下载)
1、Blob
- Blob 对象表示一个不可变、原始数据的类文件对象。
- Blob 的数据可以按文本或二进制的格式进行读取,也可以转换成ReadableStream来用于数据操作。
- Blob 对象是html5新增的对象,它的作用是用来存储二进制数据的,比如图片、视频、音频等。
使用方法如下:
/**
* @param {Array} array 二进制数据
* @param {Object} options 配置项
* @param {String} options.type 文件类型,它代表了将会被放入到 blob 中的数组内容的 MIME 类型。
* @param {String} options.endings 用于指定包含行结束符\n的字符串如何被写入。默认为transparent,表示不会修改行结束符。还可以指定为native,表示会将\n转换为\r\n。
*/
const blob = new Blob([], { type: '' })
2、URL.createObjectURL
URL.createObjectURL() 是一个 JavaScript 方法,它用于创建一个指向 Blob 或 File 对象的 URL。这个方法非常适用于处理文件上传、图像预览、视频播放等场景。通过这个 URL,你可以在浏览器中访问本地文件或生成的 Blob 数据,而无需将其上传到服务器。
let objectURL = URL.createObjectURL(blob);
3、URL.revokeObjectURL
URL.revokeObjectURL() 是一个在 Web API 中提供的函数,用于释放先前通过 URL.createObjectURL() 创建的对象 URL。当不再需要这个 URL 时调用 revokeObjectURL() 是非常重要的,以便释放浏览器的资源,防止内存泄漏。
URL.revokeObjectURL(objectURL);
4、下载实现
(1)将后端返回的blob类型数据,通过URL.createObjectURL(blob)转化为url;
(2)生成a标签dom元素,把url赋值到href属性,手动触发a标签点击事件下载文件;
(3)移除a标签dom元素,通过URL.revokeObjectURL(url)释放资源;
const xhr = new XMLHttpRequest();
xhr.open("get", "https://httpbin.org/bytes/1000");
xhr.responseType = "blob";
xhr.send();
xhr.onload = function () {
if (this.status === 200 || this.status === 304) {
const url = URL.createObjectURL(this.response);
const a = document.createElement("a");
a.style.display = "none";
a.href = url;
a.download = name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}
};
五、form表单
通过form表单来实现文件下载,可以通过创建和添加其他表单元素(例如隐藏的input元素),以便传递数据或参数。
downloadFile() {
// 创建一个form元素
const form = document.createElement('form');
form.method = 'GET';
form.action = 'http://example.com/file.pdf';
// 创建一个隐藏的input元素用于传递参数(可选)
const input = document.createElement('input');
input.type = 'hidden';
input.name = 'param1';
input.value = 'value1';
form.appendChild(input);
// 将form元素添加到页面中
document.body.appendChild(form);
// 提交表单进行文件下载
form.submit();
// 移除动态创建的form元素
document.body.removeChild(form);
}