Data URI üreteci

Bir görseli, yazı tipini veya metni data: URI olarak kodlayın ya da birini çözün; Base64 ile yüzde kodlaması ölçülerek karşılaştırılır. Tarayıcınızda çalışır.

Kaynak
ya da buraya bırakın — yerel olarak okunur, hiçbir zaman yüklenmez
Sonuç
data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%2024%2024'%20fill='none'%20stroke='%232563eb'%20stroke-width='2'%3E%3Ccircle%20cx='12'%20cy='12'%20r='9'/%3E%3Cpath%20d='M8%2012.5l2.5%202.5%205-6'/%3E%3C/svg%3E

Burada yüzde kodlaması daha kısa: 272 yerine 255 karakter, 17 tasarruf.

Boyutlar

Kaynak bayt
174
URI, Base64
272
URI, yüzde kodlamalı
255

Bir adresin içindeki dosya

data URI, bir adres biçiminde yazılmış koca bir dosyadır. Tarayıcının gidip alması gereken bir kaynağı göstermek yerine baytların kendisini taşır; böylece bir simge onu kullanan stil sayfasının içinde, küçük bir görsel de onu gösteren HTML'in içinde yaşayabilir. RFC 2397 bu şemayı 1998'de tanımladı ve yirmi yıldır her yerde destekleniyor.

Dilbilgisi kısadır. Şema adından sonra isteğe bağlı bir ortam türü ve isteğe bağlı parametreler, ardından isteğe bağlı bir base64 imi, sonra bir virgül, sonra da veri gelir. Virgülden öncesi başlık, sonrası yüktür — tarayıcının ilk virgülden bölmesinin ve yükün içindeki bir virgülün zararsız olmasının nedeni budur.

data:[<mediatype>][;base64],<data>

data:,hello                          text/plain;charset=US-ASCII
data:text/plain;charset=utf-8,hello  the same bytes, spelled out
data:image/png;base64,iVBORw0KGgo=   binary, Base64 encoded
data:image/svg+xml,%3Csvg%20...      markup, percent-encoded

Boş bir başlık geçerlidir ve anlamı text/plain;charset=US-ASCII'dir; şartnamenin size verdiği tek varsayılan budur. Bu sayfa, hiç yazmadığınız bir ortam türünü öylece göstermek yerine bunu uyguladığını bildirir.

İki kodlama ve hangisinin kısa olduğu

RFC yükü yazmanın iki yolunu tanımlar ve bu seçim bir üslup meselesi değildir: belirli bir dosya için biri belirgin biçimde kısadır ve hangisinin kısa olduğu tamamen dosyanın içeriğine bağlıdır.

Base64 her üç baytı 64 karakterlik bir abeceden dört karakter olarak yeniden yazar. Maliyet sabit ve öngörülebilirdir: tam olarak üçte bir fazlası, artı dolgu. Her şeyle çalışır; insanların önce ona uzanmasının nedeni de budur.

Yüzde kodlaması, bir adreste geçerli olan her karakteri olduğu gibi bırakır ve olmayan her karakter için üç karakter harcar. Çoğunlukla düz ASCII'den oluşan bir yükte — bir SVG, küçük bir stil sayfası, bir JSON parçası — baytların çoğu dokunulmadan geçer ve sonuç Base64'ten kısa çıkar, çoğu zaman yüzde yirmi ile otuz arasında. Neredeyse her baytın kaçırılması gereken bir PNG'de veya yazı tipinde ise özgün boyutun üç katına yaklaşır ve Base64'ten çok daha kötüdür.

Ne kadarının kaçırılacağı da başlı başına bir karardır ve bu sayfa iki yanıtı da sunar:

  • Katı küme, RFC 3986'nın ayrılmamış karakterlerinin — harfler, rakamlar, kısa çizgi, nokta, alt çizgi ve tilde — dışındaki her baytı kaçırır. Sonuç her bağlamda güvenlidir; bedeli, buna ihtiyacı olmayan noktalama işaretlerini de kaçırmaktır.
  • En az küme, data URI dilbilgisinin gerçekten izin verdiği her şeyi korur; bunlara eğik çizgiler, iki nokta, eşittir işaretleri, tırnaklar ve işaretlemenin dolu olduğu parantezler dâhildir. Yüzde kodlamasının kazandığı yer burasıdır ve öznitelikleri tek tırnak içine alınmış bir SVG'nin çift tırnaklı olandan çok daha iyi kodlanmasının nedeni de budur.
  • Hedef bir kural daha ekler. HTML özniteliğinin içinde çıplak bir ve işareti karakter başvurusu başlatır; bu yüzden img hedefini seçmek onu da kaçırır. Başka hiçbir şey değişmez: çift tırnak, açılı ayraçlar ve ters eğik çizgi zaten izin verilen kümenin dışındadır ve her iki düzeyde de kaçırılır.
  • Yüzde işareti her düzeyde daima kaçırılır. Bir kaçış dizisi başlattığı için, harfi harfine bir yüzde %25 yazılmalıdır; yoksa sonraki iki karakter onaltılık olarak okunur.

Sizi tahmine bırakmak yerine sayfa yükü her iki yolla kodlar, iki uzunluğu ve aradaki farkı bildirir. Kazananı seçin ya da bir nedeniniz varsa kodlamayı elle belirleyin.

%33 sıkıştırmadan önceki sayıdır

data URI üzerine yapılan hemen her tartışma, Base64'ün dosya boyutuna üçte bir eklediğini yineler. Aritmetik olarak doğru, pratikte yanıltıcıdır; çünkü bu sayı baytları hatta çıkmadan önce anlatır ve her sunucu metni çıkışta sıkıştırır.

Base64 bilgi eklemez; aynı bilgiyi daha çok karaktere yayar ve bir baytın alabileceği 256 değerin yalnızca 64'ünü kullanır. Bu, gzip ile Brotli'nin kaldırmak için var olduğu türden bir fazlalıktır. Zaten sıkıştırılmış bir yükte — PNG, JPEG, WOFF2 yazı tipi — sıkıştırıcı asıl veriye dokunamaz ama Base64'ü özgün boyuta çok yakın bir yere geri sıkıştırabilir. O meşhur üçte bir büyük ölçüde kaybolur.

Bu yüzden bu sayfa iddia etmek yerine ölçer. Tarayıcının kendi gzip gerçeklemesiyle üç şeyi sıkıştırır: yükü ayrı bir dosya olarak sunulacağı hâliyle, onu Base64 olarak taşıyan belgeyi ve onu yüzde kodlamasıyla taşıyan belgeyi. Bu üç sayı boyut savının dürüst sürümüdür ve gömmenin gerçek bedelinin çoğu zaman boyut olmadığını gösterir.

Gerçek bedeller başka yerdedir. Gömülü bir dosya kendi başına önbelleğe alınamaz; onu taşıyan belgenin her kopyasıyla yeniden indirilir ve iki sayfa arasında hiçbir zaman paylaşılmaz. Ayrıca engeller: bir stil sayfası, tam ortasında oturan URI'yi baştan sona okumadan ayrıştırmayı bitiremez. Gömmeyi baştan çekici kılan istek başına bedeli HTTP/2 büyük ölçüde ortadan kaldırdı. Her sayfada görünen minik bir simge için hâlâ makul bir takas; birkaç on kilobaytı aştıktan sonra genellikle değil ve bu sayfanın otuzda uyarmaya başlamasının nedeni budur.

Tür baytlardan gelir

Bir data URI ancak ortam türü doğruysa işe yarar. Yanlış olursa tarayıcı görseli göstermeyi reddeder, yanlış ayrıştırıcıyı çalıştırır ya da tanımadığı bir türle sunulan her şey için indirme önerir.

Bir dosya bıraktığınızda tarayıcı kendi türünü bildirir, ama bu bildirim yalnızca dosya uzantısından türetilmiştir. Bir JPEG'in adını .png yapın, tarayıcı ona PNG diyecektir. Bu sayfa bunun yerine ilk baytları okur. Neredeyse her ikili biçim bir imzayla başlar: PNG, ASCII'de bulunamayacak bir baytla ve ardından PNG harfleriyle; JPEG üç sabit baytla; PDF bir yüzde işareti ve PDF sözcüğüyle; WOFF ile WOFF2 kendi dört karakterlik etiketleriyle. İmza ile uzantı çeliştiğinde imza kazanır ve çelişki bildirilir.

Liste bilerek kısa tutulmuştur: bir tarayıcının koklayabileceği her şey değil, insanların gerçekten gömdüğü biçimler. Hiçbiri uymazsa ve baytlar geçerli metinse tür metindir; SVG ile XML, işaretlemenin neyle açıldığına bakılarak ayrılır. Hiçbir şey uymazsa yanıt application/octet-stream olur ve alan düzenlenebilir kalır; çünkü yanlış bir tahmin, itiraf edilmiş bir bilgisizlikten kötüdür.

Metin yüklerinde karakter kümesi de önemlidir. Şartnamenin varsayılanı US-ASCII'dir ki bugün kimse bunu kastetmez; bu yüzden metin türündeki bir ortam türü charset=utf-8 eklenmiş olarak sunulur. Onu atlamak baytları bozmaz ama geri okunma biçimini değiştirir.

Birini geri okumak

İşin öteki yarısı daha sık başa gelir: bir stil sayfasında, bir DOM dökümünde ya da kaydedilmiş bir sayfada bir data: URI buldunuz ve onun ne olduğunu bilmek istiyorsunuz. Yapıştırın; sayfa onu parçalarına ayırsın — ortam türü, parametreleri, hangi kodlamanın kullanıldığı, kaç bayta çözüldüğüne karşılık kaç karaktere mal olduğu ve başlığın iddiasından bağımsız olarak o baytların ne olduğu. Görsel çizilir, metin gösterilir, geri kalan her şey ilk baytlarını onaltılık olarak alır.

Çözme katıdır; çünkü yapıştırılmış bir URI güvenilmez girdidir ve akla yatkın ama yanlış bir yanıt hatadan kötüdür. Eksik bir virgül, bozuk bir ortam türü, ardından iki onaltılık basamak gelmeyen bir yüzde işareti, Base64 abecesi dışında bir karakter: her biri sessizce onarılmak yerine sorunun konumuyla birlikte başarısız olur.

İki şeye hoşgörü gösterilir; çünkü her tarayıcı bunlara hoşgörü gösterir ve satır kaydırmalı bir stil sayfasından kopyalanmış bir URI aksi hâlde kullanılamaz olurdu. Yükün içindeki boşluklar kaldırılır ve eksik Base64 dolgusu tamamlanır. İkisi de bildirilir; böylece elinizdeki URI'nin her yerde çalışan URI ile tam olarak aynı olmadığını bilirsiniz.

Buna benzeyen bir şey ise baştan reddedilir. Artıyı ve eğik çizgiyi kısa çizgi ve alt çizgiyle değiştiren URL için güvenli Base64 abecesi, JSON Web Token'ların kullandığı şeydir — data URI'nin kabul ettiği şey değil. Onu sessizce kabul etmek, tarayıcının çözeceğinden başka baytlara çözmek anlamına gelirdi; bu yüzden kusurlu karakterin konumuyla birlikte adıyla reddedilir.

Nerede çalışıyor

Her şey tarayıcınızın içinde olur. Seçtiğiniz dosya yerel dosya arayüzüyle okunur ve hiçbir zaman yüklenmez; kodlama, sıkıştırma ölçümü ve çözme kendi makinenizde çalışır, hiçbir şey saklanmaz ya da günlüğe yazılmaz. Bu, çoğu sayfadan çok burada önemlidir; çünkü insanların data URI'ye çevirdiği dosyalar çoğu zaman iç kaynaklardır ve incelemek için yapıştırdıkları URI'ler canlı sayfalardan gelir.

Sıkça sorulan sorular

Dosyam bir yere yükleniyor mu?
Hayır. Dosya, tarayıcının kendi dosya arayüzüyle yerelde okunur, makinenizde kodlanır ve hiçbir yere gönderilmez. Çözmek için yapıştırdığınız bir URI için de aynısı geçerlidir.
Base64 mü yüzde kodlaması mı kullanmalıyım?
Verileriniz için hangisi kısaysa; sayfa bunu sizin yerinize ölçüyor. Kaba bir kural: SVG, CSS, JSON ve öteki metinler için yüzde kodlaması; görseller, yazı tipleri ve zaten sıkıştırılmış her şey için Base64. Fark çoğu zaman iki yönden birinde yüzde yirmi ile otuz arasındadır.
Base64 dosyayı gerçekten %33 büyütür mü?
Sıkıştırmadan önce evet: her üç bayt için dört karakter. Hatta ise çoğunlukla hayır. Base64 bir baytın alabileceği 256 değerin yalnızca 64'ünü kullanır ve gzip'in kaldırdığı şey tam olarak bu fazlalıktır; bu yüzden sıkıştırılmış boyut genellikle özgün dosyanın sıkıştırılmış boyutuna yakın çıkar. Sayfa ikisini de ölçer, kendiniz görün.
Bir data URI ne kadar büyük olabilir?
Modern tarayıcılar belge içindeki bir URI'ye katı bir sınır koymaz; gerçi Internet Explorer'ın eski sürümleri 32 KB'de kesiyordu. Boyut bir yasallık değil başarım sorunudur: gömülü dosya ayrıca önbelleğe alınamaz ve belgenin her kopyasıyla yeniden indirilir. Bu sayfa bir megabayta kadar kodlar ve otuz kilobaytın üstünde uyarır.
SVG data URI'm CSS'te neden bozuluyor?
Neredeyse her zaman kaçırılmamış bir karakter yüzünden. #2563eb gibi bir renkten gelen kare işareti bir parça tanımlayıcısı başlatır ve URI'yi o noktada keser. Çift tırnak, içinde bulunduğu CSS dizgisini bitirir. SVG'yi özniteliklerini tek tırnak içine alarak yazın ve en az kaçış kümesini kullanın; kare işaretini ve çift tırnağı kaçırır, geri kalanı kısa bırakır.
Bir betik ya da iframe için data URI kullanabilir miyim?
Kullanabilirsiniz ama bunu bir kolaylık değil güvenlik meselesi olarak ele alın. data URI hiçbir köken devralmaz ve tarayıcılar tam da bu yüzden en üst düzey gezinmeyi çoktan engelliyor. script-src ya da frame-src içinde data: izni veren bir içerik güvenliği politikası, korumaya çalıştığı şeyin büyük bölümünden vazgeçer; img-src ya da font-src içinde izin vermek ise olağandır.
URL için güvenli Base64'üm neden reddedildi?
Çünkü data URI standart Base64 kabul eder. URL için güvenli abece artıyı ve eğik çizgiyi kısa çizgi ve alt çizgiyle değiştirir; bunlar farklı karakterlerdir ve farklı baytlara çözülürler. Kabul etmek, bu sayfanın URI'nizi onu gerçekten yükleyecek tarayıcıdan başka türlü çözmesi anlamına gelirdi.
Tarayıcı dosyamın bir tür, bu sayfa başka bir tür olduğunu söylüyor. Hangisi doğru?
Sayfa. Tarayıcı türü dosya uzantısından çıkarır, dolayısıyla adı değiştirilmiş bir dosyada yanılır. Bu sayfa dosyanın başındaki imzayı, yani biçimin kendi bildirdiği şeyi okur. Geçersiz kılmak için bir nedeniniz varsa alan düzenlenebilir kalır.