2017年10月29日 星期日

Object URL簡易實作

最近在專案中需要檔案下載的功能,於是就研究一下了 Object URL 

Object URL的格式是 "blob:"網址/guid (ex: blob:http://localhost:4200/57a88ea0-5654-4633-b912-6a8fdc2f0a0f)
與先前的Data URI有明顯的差異,Data URI後面則要帶Base64編碼,那Object URL後面只帶GUID,且不管你的內容有有多大,還是用GUID,這樣看一下來Object URL效率確實比較好的。

那該如何使用呢?

可以藉由URL.createObjectURL()為File或Blob物件建立Object URL,而內容則會被儲存到瀏覽器記憶體,所以這也代表了它的生命週期與網頁緊密在一起的,而可以透過URL.revokeObjectURL()來註銷

以下則為簡單的實作

API:
// 取檔案的邏輯
var path = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Files/test.txt");
using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read))
{
    var bytes = new byte[fs.Length];
    fs.Read(bytes, 0, bytes.Length);
    var response = new HttpResponseMessage();
    response.Content = new ByteArrayContent(bytes);
    response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/octet-stream");
    response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment");
    response.Content.Headers.ContentDisposition.FileName = "test.txt";

    return response;
}
JS:
 $(function () {
     $('#btn').click(function () {
        var request = new XMLHttpRequest();
        request.open('POST', 'http://localhost:56381/files/download', true);
        request.responseType = 'blob';
        request.onload = function(e) {
            var blob = new Blob([this.response], { type: 'application/octet-stream' });
            var url = URL.createObjectURL(blob); // 建立URL
            var a = document.createElement('a');
            a.href = url;
            a.download = "test.txt"; // file name
            a.click();
            URL.revokeObjectURL(url); // 註銷URL
        };
        request.send();
    });
});


那請求的方式這裡是用原生的方式,也可以改成現有的套件或是framework。ex: Rxjs、jQuery等(jQuery似乎不支持Blob,可能要在研究一下),
如此一來有些像是post下載檔案之類的需求都可以透過這個方式去實現囉:)
範例在git唷!

Object_URL_Example

參考資料
MDN
黑大





沒有留言:

張貼留言