相信大家對於Data URI已不陌生,這回再介紹另一個HTML5的好東西 --- Object URL。
Data URI的格式為="data:image/gif;base64,R0lGOD....",Object URL則是"blob:"再串上網址以及GUID,例如: blob:http%3A//www.darkthread.net/c94d498b-7818-49b3-8e79-d3959938ba0f
大家應該已經注意到一點明顯差異 -- Object URL不像Data URI包含內容的Base64編碼,不管背後代表的File或Blob物件有多大,都只有一個短短的GUID,真正的內容被儲存在瀏覽器記憶體中,Object URL像個號碼牌,憑著它可以向瀏覽器提領內容。換個角度,http%3A//www.darkthrad.net/c94d498b-7818-49b3-8e79-d3959938ba0f的形式,有點像是跟http: //www.darkthread.net網站取得名為c94d498b-7818-49b3-8e79-d3959938ba0f的資源,但讀取時不需真的發出HTTP Request,直接由瀏覽器提取即可。由於物件內容被儲存在瀏覽器記憶體,註定了Object URL的生命週期得緊緊地跟網頁綁在一起,就像JavaScript變數一般,需等到網頁載入後,透過URL.createObjectURL()為File或Blob物件建立Object URL,網頁結束後自動失效,或是確定不要後呼叫URL.revokeObjectURL()主動將其註銷節省記憶體。(補充: File物件的使用方式可參考從桌面拖拉檔案到網頁、檔案上傳進度條)
Object URL如果標準URL,可以套用在原本使用URL的場合,例如: <img> src、<a> href,甚至當成$.ajax()的下載來源,在應用上比Data URI廣泛。來看看兩個有趣的範例:
[瀏覽器版本需求: 依循往例,IE9繼續哭哭,IE10+與其他瀏覽器都已支援]
【以JavaScript產生可下載檔案】
如以下示範,在<textarea>輸入文字,將其轉為Blob物件後建立Object URL,產生<a href="object_url" download="file_name">的下載連結,可將剛才輸入的文字匯出成檔案,很酷吧! 而按下註銷鈕後Object URL將被註銷,再下載檔案時就會失敗。Live Demo
程式碼:
<!DOCTYPEhtml>
<html>
<head>
<metaname="viewport"content="width=device-width"/>
<title>HTML5 Blob URL應用-產生可下載檔案</title>
<style>
.revoke { text-decoration: line-through; }
</style>
</head>
<body>
<div>
<textareaid='taText'style='width: 300px; height: 50px;'>
是程式問題,但程式問題不等於程式設計師的問題。
是網頁問題,但網頁問題不等於網頁攻城獅的問題。
</textarea>
<br/>
<inputtype="button"id='btnGenFile'value='產生檔案'/>
<inputtype="button"id="btnRevokeUrl"value='註銷Blob URL'/>
<br/>
<aid='aDownload'></a>
</div>
<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.js "></script>
<script>
$(function () {
var $link = $("#aDownload");
$('#btnGenFile').click(function() {
var blob = new Blob([$("#taText").text()],
{ type:"application/octect-stream" });
var blobUrl = URL.createObjectURL(blob);
var fileName = "words.txt";
$link.attr({ href: blobUrl, download: fileName })
.text(fileName).removeClass("revoke");
});
$('#btnRevokeUrl').click(function() {
URL.revokeObjectURL($link.attr("href"));
$link.addClass("revoke");
});
});
</script>
</body>
</html>
【模擬XHR下載來源】
第二個示範也很有趣,我寫了一段$.get()由指定的網址下載內容,顯示於下方<textarea>。第一次先輸入httq:jsbin.com/xocul(網頁在jsbin.com執行時,URL必須是jsbin.com的網址,否則會違反XHR資安原則拒絕存取),按鈕後可取回該網址的HTML。接著,改用<input type="file">選取本機檔案,使用HTML5 File API取得該檔案的File物件,用URL.createObjectURL()轉成URL當成$.get()的URL參數,按鈕後XHR成功讀出本機檔案的內容並顯示在下方。Live Demo
程式碼:
<!DOCTYPEhtml>
<html>
<head>
<metaname="viewport"content="width=device-width"/>
<title>HTML5 Blob URL應用-XHR網址來源</title>
<style>
</style>
</head>
<body>
<div>
<inputtype="file"id="fileSelector"/>
<br/>
URL: <inputtype="text"id="txtUrl"style="width: 60%"/>
<br/>
<inputtype="button"id='btnReadFile'value='XHR讀取檔案'/>
<br/>
<textareaid="taDisplay"style="width: 80%; height: 50px;"></textarea>
</div>
<scriptsrc="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.9.1.js "></script>
<script>
$(function () {
var $link = $("#aDownload");
$("#fileSelector").change(function(e) {
var file = e.target.files[0];
$("#txtUrl").val(URL.createObjectURL(file));
});
$('#btnReadFile').click(function() {
$.get($("#txtUrl").val(), function(res) {
$("#taDisplay").text(res);
}, "text");
});
});
</script>
</body>
</html>
學會愈多新武器,愈覺得HTML5有趣,Rock~ :P