最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

前端 javascript 實現(xiàn)文件下載的示例

 更新時間:2020年11月24日 11:56:37   作者:小蘑菇  
這篇文章主要介紹了前端 javascript 實現(xiàn)文件下載的示例

在 html5 中,a 標(biāo)簽新增了 download 屬性,包含該屬性的鏈接被點擊時,瀏覽器會以下載文件方式下載 href 屬性上的鏈接。示例:

<a  rel="external nofollow" download="baidu.html">下載</a>

1. 前端 js 下載實現(xiàn)與示例

通過 javascript 動態(tài)創(chuàng)建一個包含 download 屬性的 a 元素,再觸發(fā)點擊事件,即可實現(xiàn)前端下載。

代碼示例:

function download(href, title) {
    const a = document.createElement('a');
    a.setAttribute('href', href);
    a.setAttribute('download', title);
    a.click();
}

說明:

  • href 屬性設(shè)置要下載的文件地址。這個地址支持多種方式的格式,因此可以實現(xiàn)豐富的下載方法。
  • download 屬性設(shè)置了下載文件的名稱。但 href 屬性為普通鏈接并且跨域時,該屬性值設(shè)置多數(shù)情況下會被瀏覽器忽略。

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,允許內(nèi)容創(chuàng)建者在文檔中嵌入小文件。數(shù)據(jù)URI由四個部分組成:前綴(數(shù)據(jù):),指示數(shù)據(jù)類型的MIME類型,如果非文本則為可選的base64令牌,數(shù)據(jù)本身:

data:[<mediatype>][;base64],<data>

鏈接的 href 屬性為 data URIs 時,也可以實現(xiàn)文件內(nèi)容的下載。示例:

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 格式的內(nèi)容。

1.4 二進制內(nèi)容下載
URL.createObjectURL 方法會根據(jù)傳入的參數(shù)創(chuàng)建一個指向該參數(shù)對象的 URL。新的對象 URL 指向執(zhí)行的 File 對象或者是 Blob 對象。

URL.createObjectURL 的參數(shù)是 File 對象或者 Blob 對象,F(xiàn)ile 對象也就是通過 input[type=file] 選擇的文件,Blob 對象是二進制數(shù)據(jù)。

將URL.createObjectURL 返回值設(shè)為 href 屬性的值,即可實現(xiàn)二進制內(nèi)容下載。示例:

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 前端下載方法示例
綜合上述討論,這里給出一個前端實現(xiàn)下載的 saveAs 方法的 TypeScript 示例:

/**
 * 通過創(chuàng)建 a dom 對象方式實現(xiàn)前端文件下載
 * @param href 要下載的內(nèi)容鏈接。當(dāng)定義了 toBlob 時,可以為純文本或二進制數(shù)據(jù)(取決于 toBlob 格式
 * @param fileName 下載后的文件名稱
 * @param toBlob 如設(shè)置該參數(shù),則通過 blob 方式將 href 轉(zhuǎn)換為要保存的文件內(nèi)容,該參數(shù)將入?yún)?new Blob([href], toBlob) 的第二個參數(shù)
 * @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 新增內(nèi)容,瀏覽器支持情況可參考: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 標(biāo)簽是否存在 download 屬性。示例:

const downloadAble = 'download' in document.createElement('a');

對于不支持的瀏覽器,只能另想他法或者予以降級處理了。

3.使用 serviceWorker 和 fetch API 代理實現(xiàn)

前端下載更多的需求是因為內(nèi)容產(chǎn)生于前端。那么可以在后端實現(xiàn)一個這樣的 API ,它在接收到前端發(fā)出的內(nèi)容后返回下載格式的數(shù)據(jù)。這種實現(xiàn)就不存在瀏覽器兼容問題。

利用 serviceWorker 和 fetch API 截攔瀏覽器請求,只需實現(xiàn)好約定邏輯,也可實現(xiàn)這種功能需求。示例:

在頁面中,通過 fetch API 構(gòu)造請求:

fetch('lzwme.txt', {
    isDownload: true,
    body: {
        data: new Blob('hi!')
    }
})

在 serviceWorker 中,截攔附帶 isDownload 頭信息的請求,構(gòu)造下載回應(yīng):

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) 方式下載服務(wù)器文件

以上主要討論的是純前端實現(xiàn)下載保存文件的方法。對于下載服務(wù)器文件,最簡的方式就是 window.open(url) 和 location.href=url 了,但是其的弊端也很明顯,當(dāng)出錯時整個頁面都會掛掉,而且也無法獲得下載狀態(tài)與進度,下載時間稍長時體驗相當(dāng)不好。

下面介紹一下使用 xhr 和 fetch API 實現(xiàn)文件下載的方法。其主要思路為:將請求結(jié)果設(shè)為 Blob 類型,然后采用前端下載保存 Blob 類型數(shù)據(jù)的方式實現(xiàn)下載。

4.1 使用 xhr 下載遠(yuǎn)程服務(wù)器文件
代碼示例:

/** 前端下載/保存文件 */
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 下載遠(yuǎn)程服務(wù)器文件

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
    // })
  })

以上就是前端 javascript 實現(xiàn)文件下載的示例的詳細(xì)內(nèi)容,更多關(guān)于JavaScript 文件下載的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • JavaScript Eval 函數(shù)使用

    JavaScript Eval 函數(shù)使用

    JavaScript Eval 函數(shù)使用,需要的朋友可以參考下。
    2010-03-03
  • Jquery調(diào)用iframe父頁面中的元素及方法

    Jquery調(diào)用iframe父頁面中的元素及方法

    對于javascript操作iframe父級頁面元素的方法,大家應(yīng)該都非常清楚了,下面結(jié)合當(dāng)前非常流行的jquery分享一下如何使用jquery查找和操作iframe父級頁面元素的實現(xiàn)代碼。
    2016-08-08
  • JavaScript如何處理移動端拍攝圖片旋轉(zhuǎn)問題

    JavaScript如何處理移動端拍攝圖片旋轉(zhuǎn)問題

    這篇文章主要告訴大家JavaScript如何處理移動端拍攝圖片旋轉(zhuǎn)問題,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • js實現(xiàn)隨機圓與矩形功能

    js實現(xiàn)隨機圓與矩形功能

    這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)隨機圓與矩形功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • js獲取input標(biāo)簽的輸入值實現(xiàn)代碼

    js獲取input標(biāo)簽的輸入值實現(xiàn)代碼

    input標(biāo)簽的輸入值通過js進行獲取,部分標(biāo)簽和類是封裝在框架內(nèi)的,其效果和html標(biāo)簽差不多,具體實現(xiàn)如下,感興趣的朋友可以參考下,希望對大家有所幫助
    2013-08-08
  • javascript 二進制運算技巧解析

    javascript 二進制運算技巧解析

    javascript 中的二進制運算的一些技巧,曬出來和你們分享一下,希望可以幫助你們
    2012-11-11
  • JS實現(xiàn)根據(jù)用戶輸入分鐘進行倒計時功能

    JS實現(xiàn)根據(jù)用戶輸入分鐘進行倒計時功能

    倒計時功能大家無論在各大網(wǎng)站都可以看到,今天小編給大家分享一段基于js實現(xiàn)的根據(jù)用戶輸入分鐘進行倒計時功能,非常不錯,需要的朋友參考下吧
    2016-11-11
  • JavaScript實現(xiàn)隨機點名小程序

    JavaScript實現(xiàn)隨機點名小程序

    這篇文章主要介紹了JavaScript實現(xiàn)隨機點名小程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-10-10
  • javascript獲取指定區(qū)間范圍隨機數(shù)的方法

    javascript獲取指定區(qū)間范圍隨機數(shù)的方法

    下面小編就為大家?guī)硪黄猨avascript獲取指定區(qū)間范圍隨機數(shù)的方法。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-09-09
  • JavaScript接口防止重復(fù)請求的方法總結(jié)

    JavaScript接口防止重復(fù)請求的方法總結(jié)

    在前端開發(fā)中,防止重復(fù)請求是一個常見的問題,重復(fù)請求不僅會增加服務(wù)器的負(fù)載,還可能導(dǎo)致數(shù)據(jù)不一致等問題,本文為大家整理了一些常用的解決方法,需要的可以參考下
    2024-12-12

最新評論

满洲里市| 察雅县| 绿春县| 黑水县| 宣威市| 澄江县| 新兴县| 布拖县| 张家界市| 公安县| 富锦市| 徐水县| 犍为县| 福安市| 望都县| 唐河县| 屏东市| 达日县| 岑溪市| 赞皇县| 运城市| 博兴县| 武义县| 怀集县| 山东| 当涂县| 长宁县| 精河县| 浦县| 纳雍县| 通道| 仁化县| 鹤庆县| 广西| 彰化市| 鹤峰县| 田林县| 汨罗市| 清水县| 石阡县| 武胜县|