1. 程式人生 > >Chrome中利用HTML5實現具有檔案“編輯”及“下載”功能的本地應用

Chrome中利用HTML5實現具有檔案“編輯”及“下載”功能的本地應用

【Data URL】

最新的HTML5瀏覽器中,已經支援用Data URL(RFC2397)來引用“外部”資源了。

比如下面的連結,在HTML5瀏覽器中點選後,會轉到一個新頁面,顯示“Hello Data URL!”字樣。

<a href="data:text/plain,Hello Data URL!">Hello</a>

如果文字內容包含特殊字元怎麼辦?Data URL也是一種URL,也可以使用通用的URL轉義編碼:

<a href="data:text/html;charset=utf8,%3Ch1%3E%E4%BD%A0%E5%A5%BD%3C/h1%3E">URL escaped</a>
上面的例子都是純文字資料。其實Data URL也可以表示二進位制資料,用Base64編碼即可(當然URL轉義也能實現)。

下面是一個表示GIF圖片的Data URL(引用自RFC2397):

<a href="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7">Larry</a>

也不是所有的二進位制檔案格式都必須編碼,當實際資料不包含特殊字元的時候,不編碼也是可以的:

<a href="data:application/octet-stream,12345">octet-stream</a>
上面的連結都可以點右鍵“另存為”本地磁碟檔案,這個過程就像通常下載遠端檔案的操作一樣。 這樣的話,理論上我們可以將任何資料轉化為一個Data URL連結,以便讓使用者“下載”。

【自動下載和預設檔名】
上面已經實現了生成檔案資料並儲存到本地的功能,但是還有不足:

對於瀏覽器能夠顯示的MIME型別,點選連結的話會直接在瀏覽器中顯示,比如純文字、HTML以及圖片等型別。

若手動將連結另存,Chrome 22中文版彈出的儲存框預設主檔名永遠為“下載”,Firefox 16則是一串莫名其妙並以.part結尾的字串做預設名。

對於瀏覽器不能顯示的MIME型別,Chrome 22和Firefox 16都會自動呼叫下載功能。但是Chrome中文版下載的預設主檔名仍然總為“下載”,Firefox 16則還是莫名其妙的字串。

不過,Chrome 22中已經對<a>元素增加了一個新的標籤屬性“download”來解決這個問題。

<a href="data:text/plain,Hello Data URL!" download="hello.txt">hello</a>
<a href="data:text/html;charset=utf8,%3Ch1%3E%E4%BD%A0%E5%A5%BD%3C/h1%3E" download="URL escaped.html">URL escaped</a>
<a href="data:image/gif;base64,R0lGODdhMAAwAPAAAAAAAP///ywAAAAAMAAwAAAC8IyPqcvt3wCcDkiLc7C0qwyGHhSWpjQu5yqmCYsapyuvUUlvONmOZtfzgFzByTB10QgxOR0TqBQejhRNzOfkVJ+5YiUqrXF5Y5lKh/DeuNcP5yLWGsEbtLiOSpa/TPg7JpJHxyendzWTBfX0cxOnKPjgBzi4diinWGdkF8kjdfnycQZXZeYGejmJlZeGl9i2icVqaNVailT6F5iJ90m6mvuTS4OK05M0vDk0Q4XUtwvKOzrcd3iq9uisF81M1OIcR7lEewwcLp7tuNNkM3uNna3F2JQFo97Vriy/Xl4/f1cf5VWzXyym7PHhhx4dbgYKAAA7" download="Larry.gif">Larry</a>
<a href="data:application/octet-stream,12345" download="octet-stream.bin">octet-stream</a>
對於指定了download標籤屬性的連結,點選後,Chrome 總是會執行下載操作,並且下載儲存的預設檔名即為download的屬性值。

遺憾的是Firefox 16還不支援這樣的屬性。

另外,Chrome下載預設不提示檔案儲存位置和名稱。若希望每次都提示,可在Chrome的設定中修改。

【附】

以往要在瀏覽器中實現這麼一個另存為的功能,可以用IE的document.execCommand('SaveAs')模擬,但是對複雜的資料格式就沒法處理了。

或者配合服務端程式可以處理複雜的資料,但處理過程也變複雜了,純粹的本地應用還必須搭建一個額外的伺服器。

再就是利用HTA+FSO/ADO.Stream來生成檔案,但是各代Windows系統中沒用統一完善的通用對話方塊控制元件來實現“另存為”對話方塊,要麼單獨註冊,要麼利用Office中的對話方塊元件,或者其他方式模擬實現,結果這個非核心功能導致整個實現複雜了許多。

對於更復雜的資料,Data URL可能不太夠用,這時可以考慮功能更強大的HTML5 File API,使用createObjectURL()方法可以得到比Data URL更短的URL,這裡不作具體敘述。

關於Chrome 22支援的<a>的標籤屬性download,我是從“zip.js”(一個開源的zip壓縮解壓JS庫)的demo中發現的。實現此屬性最早的Chrome版本未知。