JavaScript怎样做下载文件的功能?
Admin 2021-10-19 群英技术资讯 405 次浏览
JavaScript怎样做下载文件的功能?有很多网站都会有提供下载文件的功能,小编觉得比较使用,因此这篇文章就给大家分享一下JS实现前端下载文件功能的具体代码,感兴趣的朋友可以参考。
在 html5 中,a 标签新增了 download 属性,包含该属性的链接被点击时,浏览器会以下载文件方式下载 href 属性上的链接。示例:
<a href="https://www.baidu.com" rel="external nofollow" download="baidu.html">下载</a>
1. 前端 js 下载实现与示例
通过 javascript 动态创建一个包含 download 属性的 a 元素,再触发点击事件,即可实现前端下载。
代码示例:
function download(href, title) { const a = document.createElement('a'); a.setAttribute('href', href); a.setAttribute('download', title); a.click(); }
说明:
1.1 普通连接下载示例
// 下载图片 download('https://lzw.me/images/gravatar.gif', 'lzwme-gravatar'); // 下载一个连接 download('https://lzw.me', 'lzwme-index.html');
1.2 href 为 data URIs 示例
data URI 是前缀为 data:scheme 的 URL,允许内容创建者在文档中嵌入小文件。数据URI由四个部分组成:前缀(数据:),指示数据类型的MIME类型,如果非文本则为可选的base64令牌,数据本身:
data:[<mediatype>][;base64],<data>
链接的 href 属性为 data URIs 时,也可以实现文件内容的下载。示例:
download('data:,Hello%2C%20World!', 'data-uris.txt'); download('data:text/plain;base64,SGVsbG8sIFdvcmxkIQ%3D%3D', 'data-uris.txt');
1.3 canvas 下载示例
对于 canvas 可以通过 toDataURL 方法取得 data URIs 格式的内容。
1.4 二进制内容下载
URL.createObjectURL 方法会根据传入的参数创建一个指向该参数对象的 URL。新的对象 URL 指向执行的 File 对象或者是 Blob 对象。
URL.createObjectURL 的参数是 File 对象或者 Blob 对象,File 对象也就是通过 input[type=file] 选择的文件,Blob 对象是二进制数据。
将URL.createObjectURL 返回值设为 href 属性的值,即可实现二进制内容下载。示例:
const content = 'Welcome to lzw.me!'; const blob = new Blob([content]); const href = URL.createObjectURL(blob); download(href, 'download-text.txt'); URL.revokeObjectURL(href);
1.5 前端下载方法示例
综合上述讨论,这里给出一个前端实现下载的 saveAs 方法的 TypeScript 示例:
/** * 通过创建 a dom 对象方式实现前端文件下载 * @param href 要下载的内容链接。当定义了 toBlob 时,可以为纯文本或二进制数据(取决于 toBlob 格式 * @param fileName 下载后的文件名称 * @param toBlob 如设置该参数,则通过 blob 方式将 href 转换为要保存的文件内容,该参数将入参为 new Blob([href], toBlob) 的第二个参数 * @example * ```js * saveAs('abc', 'abc.txt', {}); * saveAs('data:,Hello%2C%20World!', 'hello.txt'); * saveAs('https://lzw.me/images/avatar/lzwme-80x80.png', 'lzwme-logo.png'); * ``` */ export function saveAs(href: string | Blob, fileName?: string, toBlob?: PlainObject) { const isBlob = href instanceof Blob || toBlob; if (!fileName && typeof href === 'string' && href.startsWith('http')) { fileName = href.slice(href.lastIndexOf('/') + 1); } fileName = decodeURIComponent(fileName || 'download'); if (typeof href === 'string' && toBlob) href = new Blob([href], toBlob); if (href instanceof Blob) href = URL.createObjectURL(href); const aLink = document.createElement('a'); aLink.setAttribute('href', href); aLink.setAttribute('download', fileName); aLink.click(); // const evt = document.createEvent("HTMLEvents"); // evt.initEvent("click", false, false); // aLink.dispatchEvent(evt); if (isBlob) setTimeout(() => URL.revokeObjectURL(aLink.href), 100); return aLink; }
2.检测浏览器是否支持 download 属性
download 属性为 html5 新增内容,浏览器支持情况可参考:http://caniuse.com/#feat=download
<img src="https://lzw.me/wp-content/uploads/2017/04/a-download.png" alt="" width="879" height="346" class="aligncenter size-full wp-image-2330" />
判断浏览器是否支持该属性,只需要检测 a 标签是否存在 download 属性。示例:
const downloadAble = 'download' in document.createElement('a');
对于不支持的浏览器,只能另想他法或者予以降级处理了。
3.使用 serviceWorker 和 fetch API 代理实现
前端下载更多的需求是因为内容产生于前端。那么可以在后端实现一个这样的 API ,它在接收到前端发出的内容后返回下载格式的数据。这种实现就不存在浏览器兼容问题。
利用 serviceWorker 和 fetch API 截拦浏览器请求,只需实现好约定逻辑,也可实现这种功能需求。示例:
在页面中,通过 fetch API 构造请求:
fetch('lzwme.txt', { isDownload: true, body: { data: new Blob('hi!') } })
在 serviceWorker 中,截拦附带 isDownload 头信息的请求,构造下载回应:
self.addEventListener('fetch', function(event) { const req = event.request; if (!req.headers.get('isDownload')) { retrun fetch(req); } const filename = encodeURIComponent(req.url); const contentType = req.headers.get('Content-Type') || 'application/force-download'; const disposition = "inline;filename=" + filename + ";filename*=utf-8''" + filename const myBody = req.headers.get(body).data; event.respondWith( new Response(myBody, { headers: { 'Content-Type': contentType, 'Content-Disposition': disposition } }) ); });
4 使用 ajax (xhr与fetch API) 方式下载服务器文件
以上主要讨论的是纯前端实现下载保存文件的方法。对于下载服务器文件,最简的方式就是 window.open(url) 和 location.href=url 了,但是其的弊端也很明显,当出错时整个页面都会挂掉,而且也无法获得下载状态与进度,下载时间稍长时体验相当不好。
下面介绍一下使用 xhr 和 fetch API 实现文件下载的方法。其主要思路为:将请求结果设为 Blob 类型,然后采用前端下载保存 Blob 类型数据的方式实现下载。
4.1 使用 xhr 下载远程服务器文件
代码示例:
/** 前端下载/保存文件 */ function saveAs(href, fileName) { const isBlob = href instanceof Blob; const aLink = document.createElement('a'); aLink.href = isBlob ? window.URL.createObjectURL(href) : href; aLink.download = fileName; aLink.click(); if (isBlob) setTimeout(() => URL.revokeObjectURL(aLink.href), 100); } function xhrDownload(url, options = {}) { options = Object.assign({ method: 'get', headers: {} }, options); return new Promise((reslove, reject) => { const xhr = new XMLHttpRequest(); xhr.responseType = 'blob'; // options.responseType; if (options.headers) { for (const key in options.headers) xhr.setRequestHeader(key, options.headers[key]); } xhr.onload = () => { // 从 Content-Disposition 中获取文件名示例 const cd = xhr.getResponseHeader('Content-Disposition'); if (cd && cd.includes('fileName') && !options.fileName) options.fileName = cd.split('fileName=')[1]; options.fileName = decodeURIComponent(options.fileName || 'download-file'); if (+xhr.status == 200) { saveAs(xhr.response, options.fileName); reslove(options.fileName);
使用 fecth API 下载远程服务器文件
function fetchDownload(url, options = {}) { options = Object.assign({ credentials: 'include', method: 'get', headers: {} }, options); return fetch(url, options).then(response => { return response.blob().then(blob => { if (!blob || !blob.size) return Promise.reject('empty'); // 从 Content-Disposition 中获取文件名示例 const cd = response.headers.get('Content-Disposition'); if (cd && cd.includes('fileName') && !options.fileName) options.fileName = cd.split('fileName=')[1]; options.fileName = decodeURIComponent(options.fileName || 'download-file'); saveAs(blob, options.fileName); return options.fileName; }); }); } // 测试 fetchDownload('https://lzw.me/images/avatar/lzwme-80x80.png', { // method: 'post', // headers: { // 'Content-Type': 'application/json' // }, // body: JSON.stringify({ // pageSize: 100000, // startPage: 0 // }) })
以上就是JS实现前端下载文件功能的具体代码,需要的朋友可以参考学习,希望对大家学习JS有帮助,想要了解更多可以继续浏览群英网络其他相关的文章。
文本转载自脚本之家
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:mmqy2019@163.com进行举报,并提供相关证据,查实之后,将立刻删除涉嫌侵权内容。
猜你喜欢
这篇文章通过实例代码给大家介绍了vue项目中添加electron的方法,代码简单易懂,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
JS怎样实现简单的缓动动画?JS缓动动画我们之前也有简单的了解过,本文给大家分享一个简单的示例供大家参考,有需要的朋友可以了解看看,实现效果及代码如下。
这篇文章主要为大家详细介绍了vue实现简单的轮播图片,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
这篇文章我们来了解jQuery获得与失去焦点事件的方法,在网站中如果存在一些让用户填写内容的表单元素,那么我们能通过焦点事件和失去焦点事件,来给用户作出一些提示的内容。那么jQuery是如何实现获得与失去焦点事件的呢?接下来就跟随小编来一起学习一下吧!
本文实例为大家分享了JavaScript实现鼠标拖拽调整div大小的具体代码,供大家参考,具体内容如下。鼠标拖拽调整div大小的功能,类似于我们查看街景地图时,对缩小地图的操作。那么我们用JavaScript如何实现这样的效果呢?
成为群英会员,开启智能安全云计算之旅
立即注册Copyright © QY Network Company Ltd. All Rights Reserved. 2003-2020 群英 版权所有
增值电信经营许可证 : B1.B2-20140078 粤ICP备09006778号 域名注册商资质 粤 D3.1-20240008