ArrayBuffer ve viewâlar, JavaScriptâin bir parçası olan ECMA standardının bir parçasıdır.
Tarayıcıda baÅta Blob olmak üzere, File APIâda tanımlanmıŠolan çeÅitli ek yüksek seviye nesneler de bulunur.
Blob, isteÄe baÄlı bir type karakter dizisi (genellikle bir MIME tipi) ve buna ek olarak blobParts â BaÅka Blob objelerinin, stringlerin ve BufferSourceların bir dizisi â bölümlerinden meydana gelir.
Kurucu sözdizimi Åu Åekildedir:
new Blob(blobParts, options);
blobParts,Blob/BufferSource/StringdeÄerlerinden oluÅan bir dizidir.optionsisteÄe baÄlı objesi:typeblob tipidir ve genellikleimage/pnggibi bir MIME tipidir.endings, blobâun mevcut iÅletim sisteminin yeni satır karakterlerine (\r\n\veya\n) uyumlu olabilmesi için satır sonu karakterlerinin dönüÅtürülüp dönüÅtürülmeyeceÄi ayarı. Varsayılan olarak"Åeffaf"(hiçbir Åey yapma) Åeklindedir, fakat aynı Åekilde"yerel"(dönüÅtür) deÄeri de alabilir.
ÃrneÄin:
// bir karakter dizisinden Blob oluÅtur
let blob = new Blob(["<html>â¦</html>"], {type: 'text/html'});
// not: ilk argüman bir dizi olmalıdır [...]
// tipli dizi ve karakter dizilerinden bir Blob oluÅtur
let hello = new Uint8Array([72, 101, 108, 108, 111]); // ikili formatta "hello" deÄeri
let blob = new Blob([hello, ' ', 'world'], {type: 'text/plain'});
Blob dilimlerini Åöyle çıkartabiliriz:
blob.slice([byteStart], [byteEnd], [contentType]);
byteStartbaÅlangıç Byteâı, varsayılan olarak 0âdır.byteEndson Byte (özel, varsayılan olarak sona kadardır)contentTypeyeni blobâuntypeı, varsayılan olarak kaynakla aynıdır
Argümanlar array.slice ile benzerdir, negatif sayılar da kabul edilir.
Blobâtaki bir veriyi doÄrudan deÄiÅtiremeyiz fakat blobâu parçalara bölerek bunlardan yeni blobâlar yaratıp bunları da yeni bir blobâta birleÅtirebiliriz vesaire.
Bu durum JavaScript karakter dizilerininkine benzerdir: bir karakter dizisindeki bir karakteri deÄiÅtiremeyiz, fakat düzeltilmiÅ yeni bir karakter dizisi oluÅturabiliriz.
URL olarak Blob
Bir Blob <a>, <img> gibi etiketler için, içeriklerini göstermek adına kolayca URL olarak kullanılabilir.
type özelliÄi saÄ olsun aynı zamanda blob indirip yükleyebiliriz ve doÄal bir Åekilde Content-Type deÄerini de aÄ isteÄi içerisinde taÅıyor olacaktır.
Basit bir örnekle baÅlayalım. Linke
tıkladıÄınızda Merhaba Dünya içeriÄini taÅıyan, dinamik olarak oluÅturulmuÅ bir blobâu bir dosya olarak indirebiliyor olun.
<!-- download özelliÄi tarayıcıyı adrese gitmektense indirmeye zorlayacaktır -->
<a download="hello.txt" href='#' id="link">İndir</a>
<script>
let blob = new Blob(["Merhaba Dünya!"], {type: 'text/plain'});
link.href = URL.createObjectURL(blob);
</script>
Aynı zamanda JavaScriptâte bir link yaratabilir ve tıklama eylemini link.click() ile simüle edebiliriz, ardından indirme otomatik olarak baÅlayacaktır.
AÅaÄıda hiç HTML içermeden kullanıcının yaratılmıŠbir Blobâu otomatik olarak indirmesini saÄlayacak bir kod yer alıyor:
let link = document.createElement('a');
link.download = 'merhaba.txt';
let blob = new Blob(['Merhaba Dünya!'], {type: 'text/plain'});
link.href = URL.createObjectURL(blob);
link.click();
URL.revokeObjectURL(link.href);
URL.createObjectURL, bir blobâu alır ve ondan blob:<kaynak>:<uuid> formatında benzersiz bir URL oluÅturur.
link.hrefin deÄeri Åunun gibi olacaktır:
blob:https://tr.javascript.info/1e67e00e-860d-40a5-89ae-6ab0cbee6273
URL.createObjectURL ile oluÅturulmuÅ her bir URLâin tarayıcısı, url â blob iç adreslemesini barındırır. Bu nedenle URLâler kısadır fakat blobâa eriÅmeye izin verir.
OluÅturulmuÅ URL (ve dolayısıyla onunla baÄlantılı link) yalnızca içinde bulunduÄu mevcut belge için, açık olduÄu sürece geçerlidir ve <img>, <a> gibi, bir URL bekleyen herhangi bir objedeki blobâu göstermeyi saÄlar.
Ancak burada bir yan etki vardır. Bir blob adreslendiÄinde blobâun kendisi hafızada bulunur. Tarayıcı onu hafızadan silemez.
Adresleme döküman kapatıldıÄında otomatik olarak silinir, böylece blobâlar temizlenmiÅ olur. Ancak uygulama uzun ömürlü bir yapıdaysa bu hemen gerçekleÅmeyecektir.
Bu nedenle yeni bir URL oluÅturduÄumuzda ona ihtiyacımız kalmasa bile blob hafızada tutulmaya devam edecektir.
URL.revokeObjectURL(url), referansı iç adreslemeden silecektir; böylece blobâun silinmesini (eÄer baÅka referans kalmadıysa) ve hafızanın boÅaltılmasını saÄlayacaktır.
Son örnekte blobâun yalnızca bir kere anlık indirme için kullanılacaÄı bir senaryo oluÅturduk ve direkt olarak URL.revokeObjectURL(link.href) metodunu çaÄırdık.
Ancak tıklanabilir bir HTML linki bulunan önceki örnekte URL.revokeObjectURL(link.href) metodunu çaÄırmadık çünkü bu durum blobâu geçersiz kılacaktı. Kaldırmanın ardından adreslemenin silinmesiyle URL bir daha çalıÅmayacaktı.
Blobâtan base64âe
URL.createObjectURLâa bir alternatif de blobâu base64 olarak kodlanmıŠbir karakter dizisine dönüÅtürmek.
Bu kodlama, ikili veriyi oldukça güvenilir Åekilde 0âdan 64âe ASCII kodlarından oluÅan âokunabilirâ karakterlerle temsil eder ve daha da önemlisi bu kodlamayı âveri URLâleriâ içinde kullanabiliriz.
Bir veri URLâi data:[<mediatype>][;base64],<data> formundadır. Bu tür URLâleri sıradan URLâlerle birebir aynı Åekilde her yerde kullanabiliriz.
ÃrneÄin bu bir gülümseme ifadesi:
<img src="data:image/png;base64,R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7">
Tarayıcı bu karakter dizisini çözecek ve resmi gösterecek:
Blobâu base64âe çevirmek için FileReader yerleÅik objesini kullanacaÄız. Bu, blobâlardan birçok formatta veri okuyabilmekte. bir sonraki bölümde bunu daha derinlemesine ele alacaÄız.
AÅaÄıdaki bir blob indirmenin bu defa base64 ile olan bir demosu:
let link = document.createElement('a');
link.download = 'merhaba.txt';
let blob = new Blob(['Merhaba Dünya'], {type: 'text/plain'});
let reader = new FileReader();
reader.readAsDataURL(blob); // blob'u base64'e çevirir ve onload'ı çaÄırır
reader.onload = function() {
link.href = reader.result; // veri URL'i
link.click();
};
Bir blob oluÅturmanın bu iki yolu da kullanılabilir ancak genellikle URL.createObjectURL(blob) daha basit ve hızlıdır.
- Hafızaya önem veriyorsak kaldırmamız gerekiyorâ¦
- Blobâa doÄrudan eriÅim. âKodlama/çözmeâ yok.
- Herhangi bir Åey kaldırmamız gerekmiyor.
- Performans ve hafıza büyük blobâların kodlanması için harcanır.
Resimâden blobâa
Bir resmin blobâunu oluÅturabiliriz, bir resim parçası olabilir veya sayfanın ekran görüntüsünü dahi oluÅturabiliriz. Bir yerlere yükleme yapmak için oldukça kullanıÅlı.
Resim iÅlemleri <canvas> öÄesi aracılıÄıyla yapılır:
- Canvas üzerinde canvas.drawImage kullanarak bir resim çiz (veya bir parçasını).
- Canvasâın bir blob oluÅturan ve tamamlandıÄında
callbackini çalıÅtıran .toBlob(callback, format, quality) metodunu çaÄır.
AÅaÄıdaki örnekte resim henüz kopyalanmıŠancak bu durumda onu kesebiliriz veya bir blob oluÅturmadan önce dönüÅtürebiliriz:
// bir resim al
let img = document.querySelector('img');
// aynı boyutlarda <canvas> oluÅtur
let canvas = document.createElement('canvas');
canvas.width = img.clientWidth;
canvas.height = img.clientHeight;
let context = canvas.getContext('2d');
// resmi içine kopyala (bu metot resmi kesmeye izin verir)
context.drawImage(img, 0, 0);
// context.rotate() yapabiliriz ve canvas üzerinde birçok baÅka iÅlemde bulunabiliriz
// toBlob asenkron bir iÅlem, tamamlandıÄında callback çaÄırılacak
canvas.toBlob(function(blob) {
// blob hazır, indir
let link = document.createElement('a');
link.download = 'example.png';
link.href = URL.createObjectURL(blob);
link.click();
// tarayıcının hafızadan temizleyebilmesi için iç blob referansını sil
URL.revokeObjectURL(link.href);
}, 'image/png');
If we prefer async/await instead of callbacks:
let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));
For screenshotting a page, we can use a library such as https://github.com/niklasvh/html2canvas. What it does is just walks the page and draws it on <canvas>. Then we can get a blob of it the same way as above.
Blobâtan ArrayBufferâa
Blob kurucu metodu, herhangi bir BufferSource içeren neredeyse her Åeyden bir blob yaratabilmeye olanak saÄlar.
Yine de düÅük seviye bir iÅleme ihtiyacımız varsa FileReaderı kullanarak en düÅük seviyeli ArrayBufferı alabiliriz:
// blob'tan fileReader al
let fileReader = new FileReader();
fileReader.readAsArrayBuffer(blob);
fileReader.onload = function(event) {
let arrayBuffer = fileReader.result;
};
Ãzet
ArrayBuffer, Uint8Array ve diÄer BufferSourcelar "ikili veri"ler iken Blob "tipi olan ikili veri"yi temsil eder.
Bu, Blobâları tarayıcıda çok yaygın olan indirme/yükleme iÅlemleri için uygun hale getirir.
XMLHttpRequest, fetch gibi web isteÄi gerçekleÅtiren metotlar, diÄer ikili verilerle olduÄu gibi Blob ile de doÄal olarak çalıÅabilir.
Blob ve düÅük seviye ikili veri tiplerini kolayca birbiri arasında dönüÅtürebiliriz:
new Blob(...)kurucu metodunu kullanarak tipli bir diziden bir blob oluÅturabiliriz.- Blobâtan
ArrayBufferaFileReader kullanarak dönebiliriz ve ardından düÅük seviye ikili veri iÅleme iÅlemleri için bir view oluÅturabiliriz.
Yorumlar
<code>kullanınız, birkaç satır eklemek için ise<pre>kullanın. EÄer 10 satırdan fazla kod ekleyecekseniz plnkr kullanabilirsiniz)