js 本地下载的 几种办法:
1、a标签的download属性 适用于同源url,非同源的会走浏览器默认行为
// 下载 通过a 标签 download 属性协助下载
// 同源的可以自定义下载名称,非同源下载名称取url的名称, 所以最好下载url链接名称为文件名称
export const downloadFile = (url: string, name?: string): void => {
const link = document.createElement('a');
if (name) {
link.setAttribute('download', name);
}
// 不同源的会走浏览器默认行为
link.setAttribute('href', url);
link.click();
link.remove();
};
2、iframe 隐形下载
// iframe 隐形下载
// 不能自定义图片下载的名称
// 当时实验的时候 此方法也是网页下载, 大文件不推荐
/* dom 部分 用于下载 */
<iframe id='ifile' style={{ display: 'none' }}></iframe>
/* js部分 用于下载 */
export const doenloadFun = (url: string) => {
const iframe: any = document.getElementById('ifile');
iframe.src = url + (url.indexOf('?') > -1 ? '&' : '?') + 'response-content-disposition=attachment';
}
3、对于非同源的文件下载1 修改方法1, 此方法和iframe 隐形下载差不多
// 下载不同源文件
// 通过创建get请求url 返回文件类型, 再走方法1下载
// 此方法走浏览器下载
export const downloadFileDiffSource = (url: string, name: string): void => {
const link = document.createElement('a');
if (name) {
link.setAttribute('download', name);
}
const newUrl = url + (url.indexOf('?') > -1 ? '&' : '?') + 'response-content-disposition=attachment'
link.setAttribute('href', newUrl);
link.click();
link.remove();
};
4、对于非同源的文件下载2 搭配方法1
// 下载不同源文件
// 通过创建get请求url 返回文件, 再走方法1下载
// 此方法须请求文件回来, 如果文件类型太大了占用资源, 容易卡住,大文件不推荐
export const downloadFileDiffSource2 = (url: string, name: string): void => {
const x = new XMLHttpRequest();
x.open('GET', url, true);
x.responseType = 'blob';
x.onload = () => {
if (x.status !== 200) {
console.log('下载异常!');
return;
}
// 创建url 再走 a 标签 download 属性协助下载
const url = window.URL.createObjectURL(x.response);
downloadFile(url, name);
URL.revokeObjectURL(url);
};
x.send();
};
总结: 下载大文件 尽量使用 url + response-content-disposition=attachment 这种浏览器下载, 浏览器对于大文件可以支持分片,能暂停、开始 省不少事,如果自己网页请求大文件,非常耗费资源,容易造成阻塞,不是很推荐
图片下载问题:
在下载图片时遇到了一个问题, 就是文件下载都能实现, 但是只有图片类型会下载失败 报strict-origin-when-cross-origin:
问题分析:
1、原先存储库下载权限未开启 跨域
2、开启后还是失败,报strict-origin-when-cross-origin
3、图片有缓存
4、浏览器强刷 清除缓存再试, 成功了
最终结论是:浏览器存在跨域和非跨域的请求,导致缓存了非跨域的请求,后续跨域的请求用了浏览器缓存所以被浏览器跨域机制拦截了
解决办法浏览器缓存 对于图片浏览器缓存和业务上跨域的请求的建议,也推荐使用如下其中一个方案:
(1).使用Cache-Control头部关闭缓存,如在 COS 上传的时候加上头部Cache-Control:no-cache。
(2).设置 标签的 crossorigin 属性的值为 anonymous,强制图片每次请求都使用 XHR 的 CORS 请求。
(3).AJAX 请求图片的时候加上随机参数。
(4).开启vary