<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                [TOC] >[success] # 下載文件功能 <br/> [參考文檔:關于前端實現文件下載功能](https://segmentfault.com/a/1190000019359452#item-1) [參考文檔:前端文件下載的正確打開方式](https://mp.weixin.qq.com/s/eHeQI-nJ2tNq6AmTmhLLnw) 文件下載方式有`3種方式`和`批量下載并且打包`: 1. window.open() 2. 通過a標簽打開新頁面下載 3. 通過文件流(blob)的方式下載 4. 如何實現批量下載打包 <br/> >[success] ## window.open()打開新頁面下載文件 <br/> ~~~ 使用場景:下載'excel'文件,后端提供接口,接口返回的是'文件流',可以直接使用'window.open()',最簡單 的方式。 優點:最簡潔。 弊端:當'參數錯誤'時,或其它原因導致接口'請求失敗',這時'無法監聽到接口返回的錯誤信息',需要保證請求 必須是正確的且能正確返回'數據流',不然打開新頁面會'直接輸出接口返回的錯誤信息',體驗不好。 ~~~ <br/> 1. index.html ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>下載文件</title> <script> window.onload = function () { document.querySelector('button').onclick = function () { const URL = 'download.io' // 接口 window.open(URL, '文件名') } } </script> </head> <body> <button>下載文件</button> </body> </html> ~~~ <br/> >[success] ## a標簽打開新頁面下載文件 <br/> ~~~ 通過'a標簽'下載的方式,同'window.open()'是一樣的,唯一的優點是可以'自定義下載后的文件名','a標簽' 里有'download屬性可以自定義文件名',如果不指定,那么下載的文件名就會根據請求內容的 'Content-Disposition' 來確定,如果沒有 'Content-Disposition' ,那么就會使用請求的 'URL' 的 '最后一部分作為文件名'。 弊端:同window.open()方式一樣,無法監聽錯誤信息。 問題:以上'兩種方式',當在下載'.mp3格式',或者'視頻文件'時,瀏覽器會'直接播放該文件',而達不到直接 '下載'的功能,此時,'當下載音視頻文件時無法使用這兩種方式'。 ~~~ <br/> 1. index.html ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>下載文件</title> <script> window.onload = function () { document.querySelector('button').onclick = function () { const URL = 'download.io' // 接口 /** * a標簽下載文件方法 * @param { String } url 接口url * @param { String } option 文件要更改的名稱 */ const exportFile = (url, fileName) => { // 創建a標簽 const link = document.createElement('a') // 獲取body元素 const body = document.querySelector('body') // 設置url下載鏈接(接口) link.href = URL // 重命名文件名稱(這個屬于html5新特性,有些瀏覽器暫時不支持,而且跨域重命名會失效) link.download = fileName // 隱藏標簽 link.style.display = 'none' // 把標簽添加到body元素最后面 body.appendChild(link) // 點擊a標簽 link.click() // 銷毀a標簽 body.removeChild(link) } // 執行下載文件方法 exportFile(URL,'奧利給') } } </script> </head> <body> <button>下載文件</button> </body> </html> ~~~ <br/> >[success] ## 通過文件流的方式下載 <br/> ~~~ 為了方便'重復使用下載功能',進行了一個簡單的封裝,思路: 1. 調用'下載接口',指定返回'數據類型blob' 2. 在'ajax攔截器'時候進行'類型判斷'如果為'媒體類型'就執行保存文件方法。 ~~~ <br/> 1. responseType的幾種值類型 <br/> ![](https://img.kancloud.cn/2e/2e/2e2ea00a71c6752c868afb9f263c09ab_1032x553.png) <br/> 2. index.html ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <script src="test.js"></script> <title>下載文件</title> <script> window.onload = function () { document.querySelector('button').onclick = function () { // 下載接口 const URL = 'download.io' // 調用下載接口 ajax({ url: URL, type: 'get', responseType: 'blob' // 設置返回的數據類型blob、 }) } } </script> </head> <body> <button>下載文件</button> </body> </html> ~~~ <br/> 3. test.js ~~~ /** * 保存文件方法 * @param { Object } blob blob二進制大對象 * @param { Object } filename 文件名稱 */ const saveAs = (blob, filename) => { if (window.navigator.msSaveOrOpenBlob) { // Navigator.msSaveBlob()方法將“ File或” 保存Blob到磁盤。 navigator.msSaveBlob(blob, decodeURI(filename)) } else { // 創建a標簽 const link = document.createElement('a') // 獲取body const body = document.querySelector('body') // 創建對象url link.href = window.URL.createObjectURL(blob) // 重命名文件名稱 link.download = decodeURI(filename) // 隱藏a標簽 link.style.display = 'none' // 把a標簽添加到body后面 body.appendChild(link) // 模擬點擊a標簽 link.click() // 刪除a標簽 body.removeChild(link) // 用來釋放一個之前已經存在的、通過調用 URL.createObjectURL() 創建的 URL 對象 window.URL.revokeObjectURL(link.href) } } /** * ajax工具函數 * @param { Object } option 該參數為對象,以下為參數說明 * @param { String } data 接口參數 * @param { String } type 請求類型 post/get * @param { String } url 接口url * @param { String } responseType 數據返回類型blob、arrayBuffer等等 * @param { Function } success 數據成功的回調函數 */ function ajax (option) { var xhr = new XMLHttpRequest(); // 如果是get,并且有參數才設置 if (option.type === 'get' && option.data) { option.url += "?"; option.url += option.data; option.data = null; // 這樣最后直接send data即可 } xhr.open(option.type, option.url); // 返回指定數據類型blob、arrayBuffer等等 xhr.responseType = option.responseType || '' // 這里是設置請求頭的授權密鑰 xhr.setRequestHeader('authorization', 'xxxxxxxxxxxx') // 這里根據項目需求而定是否添加 // 如果是post,并且有參數才設置 if (option.type == 'post' && option.data) { xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded'); } xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { var type = xhr.getResponseHeader("Content-Type"); // 獲取服務器在header上的信息 if (type.indexOf('json') != -1) { // 判斷為json格式信息 option.success(JSON.parse(xhr.responseText)) } else if (type.indexOf('xml') != -1) { // 判斷為xml格式信息 option.success(xhr.responseXML) } else if(type.indexOf('octet-stream') != -1){ // 判斷為媒體類型格式 // 獲取文件名稱 let [,filename] = xhr.getResponseHeader('Content-Disposition').split('='); // 執行保存文件方法 saveAs(xhr.response, filename) } else { // 普通字符串 option.success(xhr.responseText) } } } xhr.send(option.data); } ~~~ <br/> >[success] ## 如何實現批量下載,且打包文件 <br/> 1. index.html ~~~ <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <!-- jszip --> <script src="https://cdn.bootcss.com/jszip/3.2.2/jszip.min.js"></script> <!-- FileSaver.js --> <script src="https://cdn.bootcss.com/FileSaver.js/1.3.8/FileSaver.min.js"></script> <!-- ajax.js --> <script src="ajax.js"></script> <title>下載文件</title> <script> window.onload = function () { document.querySelector('button').onclick = function () { // 點擊下載按鈕 let urlArr = [ // 批量選中的文件Url數組 { url: 'download.io', fileName: '文件1.xlsx' }, { url: 'download.io', fileName: '文件2.xlsx' } ] /** * 批量下載并且打成zip包 * @param urlArr Array [{url: 下載文件的路徑, fileName: 下載文件名稱}] * @param filename zip文件名 */ const download = (urlArr, filename = '默認zip文件名') => { // urlArr沒有值就返回 if (!urlArr.length) return // new一個壓縮構造函數 const zip = new JSZip() // 儲存多個請求 const promisesArr = [] // 調用批量下載接口 Promise.all(urlArr.map(item => ajax({ url: item.url, type: 'get', responseType: 'blob' }))).then((res) => { for(let i=0;i<urlArr.length;i++){ zip.file(urlArr[i].fileName, res[i], { binary: true }) // 逐個添加文件 } zip.generateAsync({ type: 'blob' }).then((content) => { // 生成二進制流 saveAs(content, `${filename}.zip`) // 利用file-saver保存文件 }) }) } // 執行批量下載并且打壓縮包 download(urlArr, '我要打個壓縮包') } } </script> </head> <body> <button>下載文件</button> </body> </html> ~~~ 2. ajax.js ~~~ /** * ajax工具函數 * @param { Object } option 該參數為對象,以下為參數說明 * @param { String } data 接口參數 * @param { String } type 請求類型 post/get * @param { String } url 接口url * @param { String } responseType 數據返回類型blob、arrayBuffer等等 * @param { Function } success 數據成功的回調函數 */ function ajax (option) { return new Promise((resolve, reject) => { var xhr = new XMLHttpRequest(); // 如果是get,并且有參數才設置 if (option.type === 'get' && option.data) { option.url += "?"; option.url += option.data; option.data = null; // 這樣最后直接send data即可 } xhr.open(option.type, option.url); // 返回指定數據類型blob、arrayBuffer等等 xhr.responseType = option.responseType || '' // 這里是設置請求頭的授權密鑰 xhr.setRequestHeader('authorization', 'xxxxxxx') // 這里根據需求而定是否添加 // 如果是post,并且有參數才設置 if (option.type == 'post' && option.data) { xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded'); } xhr.onreadystatechange = function () { if (xhr.readyState == 4 && xhr.status == 200) { var type = xhr.getResponseHeader("Content-Type"); // 獲取服務器在header上的信息 if (type.indexOf('json') != -1) { // 判斷為json格式信息 option.success(JSON.parse(xhr.responseText)) } else if (type.indexOf('xml') != -1) { // 判斷為xml格式信息 option.success(xhr.responseXML) } else if(type.indexOf('octet-stream') != -1){ // 判斷為媒體類型格式 resolve(xhr.response) } else { // 普通字符串 option.success(xhr.responseText) } } } xhr.send(option.data); }) } ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看