ArrayBuffer va view lar ECMA standartining bir qismi, JavaScript ning bir qismi.
Brauzerde File API da tasvirlangan qoâshimcha yuqori darajadagi obyektlar mavjud, xususan Blob.
Blob ixtiyoriy string type (odatda MIME-type) va blobParts dan iborat â boshqa Blob obyektlari, stringlar va BufferSource ketma-ketligi.
Konstruktor sintaksisi:
new Blob(blobParts, options);
blobPartsBlob/BufferSource/Stringqiymatlarining arrayi.optionsixtiyoriy obyekt:typeâBlobturi, odatda MIME-type, masalanimage/png,endingsâBlobni joriy OS yangitolri (\r\nyoki\n) ga mos kelishi uchun qator oxirini oâzgartirish kerakmi. Standart boâyicha"transparent"(hech narsa qilmaydi), lekin"native"(oâzgartirish) ham boâlishi mumkin.
Masalan:
// string dan Blob yaratish
let blob = new Blob(["<html>â¦</html>"], {type: 'text/html'});
// esda tuting: birinchi argument array bo'lishi kerak [...]
// typed array va stringlardan Blob yaratish
let hello = new Uint8Array([72, 101, 108, 108, 111]); // "Hello" binary shaklda
let blob = new Blob([hello, ' ', 'world'], {type: 'text/plain'});
Biz Blob boâlaklarini quyidagi bilan chiqarishimiz mumkin:
blob.slice([byteStart], [byteEnd], [contentType]);
byteStartâ boshlanish bayti, standart boâyicha 0.byteEndâ oxirgi bayt (eksklyuziv, standart boâyicha oxirigacha).contentTypeâ yangi blob ningtypei, standart boâyicha manba bilan bir xil.
Argumentlar array.slice ga oâxshash, manfiy sonlarga ham ruxsat berilgan.
Blob obyektlar oâzgarmasBiz Blob da maâlumotlarni toâgâridan-toâgâri oâzgartira olmaymiz, lekin Blob ning qismlarini kesib olishimiz, ulardan yangi Blob obyektlarini yaratishimiz, ularni yangi Blob ga aralashtirishimiz va hokazolarni qilishimiz mumkin.
Bu xatti-harakat JavaScript stringlariga oâxshash: biz stringdagi belgini oâzgartira olmaymiz, lekin yangi tuzatilgan string yasashimiz mumkin.
URL sifatida Blob
Blob uning kontentini koârsatish uchun <a>, <img> yoki boshqa teglar uchun URL sifatida osongina ishlatilishi mumkin.
type tufayli biz Blob obyektlarini yuklab olish/yuklash ham mumkin va type tabiiy ravishda tarmoq soârovlarida Content-Type ga aylanadi.
Keling, oddiy misol bilan boshlaylik. Havola bosganda siz dinamik yaratilgan Blob ni hello world kontenti bilan fayl sifatida yuklab olasiz:
<!-- download xossasi brauzerga navigatsiya qilish o'rniga yuklab olishga majburlaydi -->
<a download="hello.txt" href='#' id="link">Yuklab olish</a>
<script>
let blob = new Blob(["Salom, dunyo!"], {type: 'text/plain'});
link.href = URL.createObjectURL(blob);
</script>
Shuningdek, biz JavaScript da dinamik ravishda havola yaratishimiz va link.click() orqali bosishni simulyatsiya qilishimiz mumkin, keyin yuklab olish avtomatik boshlandi.
Mana hech qanday HTML siz dinamik yaratilgan Blob ni foydalanuvchiga yuklab olishiga sabab boâladigan shunga oâxshash kod:
let link = document.createElement('a');
link.download = 'hello.txt';
let blob = new Blob(['Salom, dunyo!'], {type: 'text/plain'});
link.href = URL.createObjectURL(blob);
link.click();
URL.revokeObjectURL(link.href);
URL.createObjectURL Blob ni oladi va uning uchun blob:<origin>/<uuid> shaklida noyob URL yaratadi.
link.href ning qiymati shunday koârinadi:
blob:https://javascript.info/1e67e00e-860d-40a5-89ae-6ab0cbee6273
URL.createObjectURL tomonidan yaratilgan har bir URL uchun brauzer ichki ravishda URL â Blob mapping ni saqlaydi. Shunday qilib, bunday URL lar qisqa, lekin Blob ga kirish imkonini beradi.
Yaratilgan URL (va shuning uchun u bilan havola) faqat joriy hujjat ichida, u ochiq boâlgan vaqtda amal qiladi. Va u <img>, <a>, asosan URL kutadigan boshqa har qanday obyektda Blob ga murojaat qilish imkonini beradi.
Biroq, yon taâsir bor. Blob uchun mapping mavjud boâlsa-yu, Blob ning oâzi xotirada joylashgan. Brauzer uni boâshatish mumkin emas.
Hujjat yuklanishida mapping avtomatik ravishda tozalanadi, shuning uchun Blob obyektlar oâshanda boâshatiladi. Lekin agar ilova uzoq umr koârsa, bu tez sodir boâlmaydi.
Shunday qilib, agar biz URL yaratadigan boâlsak, oâsha Blob endi kerak boâlmasa ham xotirada osiladi.
URL.revokeObjectURL(url) ichki mapping dan havolani olib tashlaydi, shu tariqa Blob ni oâchirish imkonini beradi (agar boshqa havolalar boâlmasa) va xotirani boâshatish.
Oxirgi misolda biz Blob ning faqat bir marta, darhol yuklab olish uchun ishlatilishini maqsad qilganimiz uchun darhol URL.revokeObjectURL(link.href) ni chaqiramiz.
Bosiladigan HTML-havolali oldingi misolda biz URL.revokeObjectURL(link.href) ni chaqirmaymiz, chunki bu Blob url ni yaroqsiz qiladi. Bekor qilingandan keyin, mapping olib tashlanganidan soâng, URL endi ishlamaydi.
Blob dan base64 ga
URL.createObjectURL ga alternativa Blob ni base64-kodlangan stringga aylantirish.
Bu kodlash binary maâlumotlarni 0 dan 64 gacha ASCII-kodlari bilan oâta xavfsiz âoâqilishi mumkinâ belgilar stringi sifatida ifodalaydi. Va eng muhimi â biz bu kodlashni "data-url"larda ishlatishimiz mumkin.
Data url data:[<mediatype>][;base64],<data> shaklida. Biz bunday url larni hamma joyda âoddiyâ url lar bilan bir qatorda ishlatishimiz mumkin.
Masalan, mana smayl:
<img src="data:image/png;base64,R0lGODlhDAAMAKIFAF5LAP/zxAAAANyuAP/gaP///wAAAAAAACH5BAEAAAUALAAAAAAMAAwAAAMlWLPcGjDKFYi9lxKBOaGcF35DhWHamZUW0K4mAbiwWtuf0uxFAgA7">
Brauzer stringni decode qiladi va rasmni koârsatadi:
Blob ni base64 ga aylantirish uchun biz oârnatilgan FileReader obyektidan foydalanamiz. U Blob lardan koâplab formatlarda maâlumotlarni oâqiy oladi. Keyingi bobda biz uni chuqurroq koârib chiqamiz.
Mana blob yuklab olishning demosi, endi base-64 orqali:
let link = document.createElement('a');
link.download = 'hello.txt';
let blob = new Blob(['Salom, dunyo!'], {type: 'text/plain'});
let reader = new FileReader();
reader.readAsDataURL(blob); // blob ni base64 ga aylantiradi va onload ni chaqiradi
reader.onload = function() {
link.href = reader.result; // data url
link.click();
};
Blob dan URL yasashning ikkala usuli ham foydalanish mumkin. Lekin odatda URL.createObjectURL(blob) sodda va tezroq.
- Xotira haqida qaygâursak, ularni bekor qilishimiz kerak.
- Blob ga toâgâridan-toâgâri kirish, âkodlash/dekodlashâ yoâq
- Hech narsani bekor qilish kerak emas.
- Kodlash uchun katta
Blobobyektlarda ishlash va xotira yoâqotishlari.
Rasm dan blob ga
Biz rasmning Blob ini, rasm qismini yaratishimiz yoki hatto sahifa skrinshoti olishimiz mumkin. Buni biror joyga yuklash uchun qulay.
Rasm operatsiyalari <canvas> elementi orqali amalga oshiriladi:
- canvas.drawImage yordamida canvasda rasm (yoki uning qismi) chizing.
- Canvas usuli .toBlob(callback, format, quality) ni chaqiring, bu
Blobyaratadi va tugagandacallbackni u bilan ishga tushiradi.
Quyidagi misolda rasm shunchaki nusxalanadi, lekin biz undan kesishimiz yoki blob yasashdan oldin canvasda uni oâzgartirishimiz mumkin:
// har qanday rasmni oling
let img = document.querySelector('img');
// bir xil o'lchamdagi <canvas> yasang
let canvas = document.createElement('canvas');
canvas.width = img.clientWidth;
canvas.height = img.clientHeight;
let context = canvas.getContext('2d');
// rasmni unga nusxalang (bu usul rasmni kesish imkonini beradi)
context.drawImage(img, 0, 0);
// biz context.rotate() va canvasda ko'plab boshqa narsalarni qilishimiz mumkin
// toBlob async operatsiya, callback tugaganda chaqiriladi
canvas.toBlob(function(blob) {
// blob tayyor, uni yuklab oling
let link = document.createElement('a');
link.download = 'example.png';
link.href = URL.createObjectURL(blob);
link.click();
// brauzer xotiradan tozalash uchun ichki blob havolasini o'chiring
URL.revokeObjectURL(link.href);
}, 'image/png');
Agar biz callback oârniga async/await ni afzal korsak:
let blob = await new Promise(resolve => canvasElem.toBlob(resolve, 'image/png'));
Sahifani skrinshot qilish uchun biz https://github.com/niklasvh/html2canvas kabi kutubxonadan foydalanishimiz mumkin. U shunchaki sahifani aylanib oâtadi va uni <canvas> da chizadi. Keyin biz yuqoridagi kabi uning Blob ini olishimiz mumkin.
Blob dan ArrayBuffer ga
Blob konstruktori har qanday BufferSource dan boshlab deyarli har qanday narsadan blob yaratish imkonini beradi.
Lekin agar bizga past darajadagi qayta ishlash kerak boâlsa, blob.arrayBuffer() dan eng past darajadagi ArrayBuffer ni olishimiz mumkin:
// blob dan arrayBuffer olish
const bufferPromise = await blob.arrayBuffer();
// yoki
blob.arrayBuffer().then(buffer => /* ArrayBuffer ni qayta ishlang */);
Blob dan stream ga
2 GB dan ortiq blob ga oâqish va yozishda arrayBuffer dan foydalanish biz uchun koâproq xotira talab qiladi. Bu vaqtda biz blob ni toâgâridan-toâgâri stream ga aylantira olamiz.
Stream undan qism-qism oâqish (yoki unga yozish) imkonini beradigan maxsus obyekt. Bu bizning doiramizdan tashqarida, lekin mana misol va siz https://developer.mozilla.org/en-US/docs/Web/API/Streams_API da koâproq oâqishingiz mumkin. Stream lar qism-qism qayta ishlashga mos maâlumotlar uchun qulay.
Blob interfeysining stream() usuli oâqilganda Blob ichidagi maâlumotlarni qaytaradigan ReadableStream ni qaytaradi.
Keyin biz undan shunday oâqiy olamiz:
// blob dan readableStream olish
const readableStream = blob.stream();
const stream = readableStream.getReader();
while (true) {
// har bir takrorlash uchun: value keyingi blob fragmenti
let { done, value } = await stream.read();
if (done) {
// stream da boshqa ma'lumot yo'q
console.log('barcha blob qayta ishlandi.');
break;
}
// blob dan hozirgina o'qigan ma'lumot qismi bilan biror narsa qiling
console.log(value);
}
Xulosa
ArrayBuffer, Uint8Array va boshqa BufferSource âbinary maâlumotâ boâlsa, Blob âturi bilan binary maâlumotâ ni ifodalaydi.
Bu Blob larni brauzerde juda keng tarqalgan yuklash/yuklab olish operatsiyalari uchun qulay qiladi.
"xmlhttrequest" maqolasi topilmadi, fetch va hokazo kabi veb-soârovlarni bajaradigan usullar Blob bilan boshqa binary turlar bilan birga tabiiy ravishda ishlashi mumkin.
Biz Blob va past darajadagi binary maâlumot turlari orasida osongina aylantira olamiz:
new Blob(...)konstruktori yordamida typed array danBlobyasashimiz mumkin.blob.arrayBuffer()yordamida Blob danArrayBufferni qaytarib olishimiz va keyin past darajadagi binary qayta ishlash uchun uning ustida view yaratishimiz mumkin.
Katta blob ni boshqarish kerak boâlganda konversiya stream lar juda foydali. Siz blob dan osongina ReadableStream yaratishingiz mumkin. Blob interfeysining stream() usuli oâqilganda blob ichidagi maâlumotlarni qaytaradigan ReadableStream ni qaytaradi.
Izohlar
<code>yorlig'ini ishlating, bir nechta satrlar uchun - ularni<pre>yorlig'i bilan o'rab qo'ying, 10 satrdan ortiq bo'lsa - sandbox (plnkr, jsbin, codepenâ¦)