檔案類型介紹及其特點

來源:互聯網
上載者:User

1. 一般類型 平時比較常見的有 txt、png、jpg、zip、tar 等各種檔案格式,這些檔案格式中,一部分瀏覽器是會直接開啟連結顯示內容的,而另外一部分,瀏覽器不識別回應標頭,或者不能解析對應的格式,於是當做檔案直接下載下來了。如: <a href="http://barretlee.com/test.rar">file</a>這句代碼,若直接點開連結,瀏覽器將會直接下載該檔案。 2. dataURL類型 dataURL 也是十分常見的類型,他可以作為 src 或者 url() 的參數送進去。比較常見的有如下幾種: 文本: data:text/plain;這裡是本文內容。圖片: data:image/jpg;base64,/9j/4AAQSkZJRgABAQEA....       data:image/png;base64,/9j/4AAQSkZJRgABAQEA....base64 是用的比較廣泛的一種資料格式。 Base64格式data:[][;charset=][;base64],Base64 在CSS中的使用:.demoImg{ background-image: url("data:image/jpg;base64,/9j/4QMZRXhpZgAASUkqAAgAAAAL...."); }Base64 在HTML中的使用:<img width="40" height="30" src="data:image/jpg;base64,/9j/4QMZRXhpZgAASUkqAAgAAAAL...." />      3. Blob 流 Blob 對象表示不可變的、包含未經處理資料的類檔案對象。具體的內容可以參閱MDN文檔。 他的使用也是特別的方便,如: var aFileParts = ['<a id="a"><b id="b">hey!</b></a>'];var oMyBlob = new Blob(aFileParts, {type : 'text/html'}); // the blobBlob 接收兩個參數,一個是數群組類型的資料對象,他可以是 ArrayBuffer、ArrayBufferView、Blob、String 等諸多類型;第二個參數是 MINE 類型設定。而本文我們要用到的是 URLcreateObjectURL() 這個函數,他的作用是將一個 URL 所代表的內容轉化成一個 DOMString,產生的結果是一個 檔案對象 或者 Blob 對象。 4. 二進位流 我們利用 File API 讀取檔案的時候,拿到的是資料的二進位流格式,這些類型可以直接被 ArrayBuffer 等接收,本文中沒有用到,就不細說了。 二、JavaScript 多檔案下載 HTML5 中 a 標籤多了一個屬性——download,使用者點選連結瀏覽器會開啟並顯示該連結的內容,若在連結中加了 download 屬性,點擊該連結不會開啟這個檔案,而是直接下載。雖說是比較好用,但低版本瀏覽器不相容,這個在本節的 2 和 3 中將會講到解決方案。 在這裡,我們可以利用屬性檢測UA來判斷瀏覽器類型: h5Down = document.createElement("a").hasOwnProperty("download");var h5Down = !/Trident|MSIE/.test(navigator.userAgent); // Trodent 標識 IE111. a 標籤 download 屬性的使用 註:FF5.0 / Safari5.0 / Opera11.1 / IE9.0 不支援 download 屬性 利用 download 屬性可以直接下載單個檔案,若想點擊一次下載多個檔案,就得稍加處理下了: function downloadFile(fileName, content){    var aLink = document.createElement("a"),        evt = document.createEvent("HTMLEvents");     evt.initEvent("click");    aLink.download = fileName;    aLink.href = content;     aLink.dispatchEvent(evt);}download 屬性的作用除了讓瀏覽器忽略檔案的 MIME 類型之外,還會把該屬性的值作為檔案名稱。你可以在 chrome 控制台運行這句程式: downloadFile("barretlee.html", "./");瀏覽器會提示是否保留(下載)該 html 檔案。之前我們提到檔案類型還可能是 dataURL 或者是 Blob 流,為了讓程式也支援這些資料類型,稍微修改下上面的函數: function downloadFile(fileName, content){    var aLink = document.createElement('a');      , blob = new Blob([content])      , evt = document.createEvent("HTMLEvents");     evt.initEvent("click");     aLink.download = fileName;    aLink.href = URL.createObjectURL(blob);    aLink.dispatchEvent(evt);}new Blob([content]),現將檔案轉換成一個 Blog 流,然後,使用 URL.createObjectURL() 將其轉換成一個 DOMString。這樣我們就支援 data64 和其他資料類型的 content 了~ 2. window.open 之後 execCommand("SaveAs") 上面也提到了,儘管 download 屬性是十分便利的 H5 利器,但低版本 IE 根本不賞臉,要說方法,IE 還是有很多方式去轉換的,比如 ADOBE.STREAM 的 activeX 對象可以把檔案轉換成檔案流,然後寫入到一個要儲存的檔案中。這裡要談到的是略微方便一點的方式:先把內容寫到一個新開的 window 對象中,然後利用 execCommand 執行儲存命令,就相當於我們在頁面上按下 Ctrl+S,這樣頁面內的資訊都會 down 下來。 // 將檔案在一個 window 視窗中開啟,並隱藏這個視窗。var win = window.open("path/to/file.ext", "new Window", "width=0,height=0");// 在 win 視窗中按下 ctrl+s 儲存視窗內容win.document.execCommand("SaveAs", true, "filename.ext");// 使用完了,關閉視窗win.close();這個過程十分明了,不過這裡會存在一個問題,並不是程式的問題,而是瀏覽器的問題,如果我們用 搜狗瀏覽器 或者 360瀏覽器 開啟新視窗的話,他會新開一個標籤頁,而不是新開一個視窗,更可惡的時候部分瀏覽器不允許 window.open (這個可以設定)。所以只好另覓他法了。 3. iframe 中操作 既然新開一個視窗那麼麻煩,我就在本視窗下完成工作~ function IEdownloadFile(fileName, contentOrPath){    var ifr = document.createElement('iframe');     ifr.style.display = 'none';    ifr.src = contentOrPath;     document.body.appendChild(ifr);      // 儲存頁面 -> 儲存檔案    ifr.contentWindow.document.execCommand('SaveAs', false, fileName);    document.body.removeChild(ifr);}一般的連結我們可以直接給 iframe 添加 src 屬性,然後執行 saveAs 命令,倘若我們使用的是 data64 編碼的檔案,這個怎麼辦? var isImg = contentOrPath.slice(0, 10) === "data:image"; // dataURL 的情況isImg && ifr.contentWindow.document.write("<img src='" +         contentOrPath + "' />");這個也比較好處理,直接把檔案寫入到 iframe 中,然後在執行儲存。 三、代碼的封裝與介面介紹 1. 代碼的封裝以及相關 DEMO 封裝:lib.js DEMO:javascript-multiple-download (HTTPS,第三個有bug)            javascript-multiple-download (HTTP,測試正常) Bug 說明,經過一番細節處理之後,基本相容各個瀏覽器,我把代碼放在 https://raw.github.com 上託管,可能因為是 https 傳輸,第三個測試中報錯了,報錯的具體內容是:HTTPS 安全受到 http://rawgithub.com/barretlee/javascript-multiple-download/master/file/test.jpg 的威脅,而 test.txt 檔案沒有報錯。放到 http 協議下測試回合結果是可觀的。(這點我沒有去深究,肯定是有深層安全方面原因的,難道就因為他是 jpg圖片格式?)後面的 demo 我放在 BAE 上,沒有問題,不過沒測試 safari 和 opera。 2. 介面的調用 提供了三個介面,支援單檔案下載,多檔案下載,多檔案下載自訂命名。 1)單檔案下載 Downer("./file/test.txt");2)多檔案下載 Downer(["./file/test.txt","./file/test.txt"]);3)多檔案下載自訂命名 Downer({    "1.txt":"./file/test.txt",    "2.jpg":"./file/test.jpg"}); 檔案的 URL 如 ./file/test.txt 都可以改成 base64 或者其他格式。 四、伺服器支援與後端實現 1. 後端實現 後端實現的原理,就是在回應標頭中加入一些特殊的標記,如前端發送這樣的請求: function download(path) {    var ifrm = document.getElementById(frame);    ifrm.src = "download.php?path="+path;}後端的響應為 <?php    header("Content-Type: application/octet-stream");   header("Content-Disposition: attachment; filename=".$_GET['path']);   readfile($_GET['path']);?>告訴瀏覽器這是一個流檔案,作為附件方式發送給你,請忽略 MINE type,直接儲存。 2. 伺服器配置 若後台是 apche 作為伺服器,可以配置 htaccess 檔案: <filesmatch "\.(zip|rar)$"="">Header set Content-Disposition attachment</filesmatch>意思是只要請求的是 zip 或者 rar 類型的檔案,那麼久添加一個 Content-Disposition:attachment 的回應標頭。這樣就可以在 php 代碼中省略麻煩的操作。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.