Alat pembangun · Pengekod & penyahkod Base64
Base64 dalam JSON API: mengapa medan binari dikodkan dan berapa kosnya
· Mengapa ia penting
asas64 pengekodan
JSON tidak mempunyai jenis bait, jadi data binari biasanya dikodkan Base64 ke dalam rentetan. Siaran ini menerangkan sebab konvensyen itu wujud, kosnya dalam saiz dan CPU, dan apabila titik akhir binari yang berasingan ialah panggilan yang lebih baik.
Medan PDF yang mendominasi respons — muatan konkrit API di mana satu gumpalan Base64 mengatasi segala-galanya
Respons API mengandungi objek besar dengan satu medan yang mendominasi saiz muatan. Jawapannya ialah JSON, jadi setiap nilai ialah rentetan atau nombor. Kebanyakan medan adalah kecil: ID pengguna, cap masa, kod status. Satu medan mengandungi imageData atau FileContents dan merupakan rentetan Base64 40-kilobait. Keseluruhan respons ialah 50 kilobait. Medan tunggal itu menyumbang 80 peratus daripada pemindahan, yang kelihatan membazir kerana pelayan menghantarnya sebagai bait pada asalnya dan akhirnya pelanggan memerlukan bait semula.
Base64 menyelesaikan masalah ini: JSON tidak mempunyai jenis bait asli, jadi data binari mesti dibalut dalam rentetan. Base64 menukar bait arbitrari kepada ASCII aksara yang selamat dalam JSON. Kedua-dua pelanggan dan pelayan mesti mengekod pada hantar dan menyahkod pada menerima, menambah CPU overhed. Muatan yang terhasil adalah kira-kira satu pertiga lebih besar daripada bait mentah. Siaran ini menerangkan sebab konvensyen itu wujud, kosnya dalam amalan dan apabila melanggar kekangan JSON dengan titik akhir binari yang berasingan adalah berbaloi.
Mengapa JSON tidak boleh membawa bait mentah — rentetan mestilah teks Unicode yang sah, jadi bait sewenang-wenangnya memerlukan pembalut teks
JSON ialah format teks yang semua nilai mestilah teks Unicode yang sah. Spesifikasi mentakrifkan rentetan, nombor, boolean dan nol. Ia tidak mempunyai tatasusunan bait atau jenis penimbal. Jika API perlu mengembalikan data binari seperti imej, tandatangan kriptografi atau muat naik fail, ia tidak boleh meletakkan bait mentah ke dalam objek JSON secara langsung. Bait mungkin mengandungi aksara yang JSON parser ditafsirkan sebagai penanda struktur. Bait nol di tengah gumpalan binari boleh menamatkan rentetan lebih awal atau memecahkan penghurai.
Penyelesaian biasa ialah mengekod data binari sebagai Base64, menghasilkan rentetan ASCII aksara yang JSON parser menganggap sebagai teks biasa. Pelanggan penerima kemudian menyahkod Base64 kembali kepada bait dan menggunakannya. Langkah pengekodan ini berlaku pada tahap API, tersembunyi daripada kebanyakan pembangun, tetapi ia merupakan kos sebenar yang terkumpul apabila API mengembalikan banyak medan binari. Kos Base64 dalam kompaun JSON merentas kitaran permintaan-tindak balas. Penalti saiz adalah yang pertama: Output Base64 adalah lebih kurang 33 peratus lebih besar daripada inputnya disebabkan overhed pengekodan.
Kos: satu pertiga lagi bait, masa nyahkod dan salinan memori — di mana setiap kos muncul dalam klien biasa
Fail video 30-megabait menjadi 40 megabait apabila Base64-encoded. Memuat turun 40 dan bukannya 30 megabait memerlukan lebar jalur dan bateri pada peranti mudah alih dan masa untuk pengguna pada sambungan perlahan. Kos kedua ialah CPU kali. Pelayan mesti mengekod data perduaan sebagai Base64 sebelum ia boleh dirangkaikan menjadi JSON. Pelanggan mesti menghuraikan JSON dan kemudian menyahkod setiap medan Base64 kembali kepada bait. Untuk respons dengan berbilang medan binari atau pelanggan yang memproses beribu-ribu respons, masa CPU itu terkumpul.
Pada peranti yang dikekang seperti telefon, operasi rentetan JavaScript dan TextDecoder yang digunakan untuk penyahkodan Base64 menggunakan bateri dan memperlahankan aplikasi. Kos ketiga ialah ingatan: penghurai JSON mencipta objek rentetan untuk medan Base64, kemudian penyahkodan mencipta salinan lain sebagai Uint8Array. Medan besar dijadikan instantiated dua kali dalam ingatan sebelum aplikasi boleh menggunakannya. Contoh yang berkesan menjelaskan kos. Katakan titik akhir API mengembalikan data profil pengguna termasuk imej avatar 100-kilobait. Pelayan membaca imej daripada cakera sebagai bait, mengekodkannya ke Base64 dan memasukkannya dalam respons JSON.
Contoh yang berjaya: memeriksa medan Base64 daripada respons API — menyahkodnya dalam pelayar untuk mengesahkan perkara yang sebenarnya dihantar oleh pelayan
Respons JSON kini kira-kira 135 kilobait (33% overhed serta medan lain). Pelanggan memuat turun 135 kilobait dan bukannya 100. Dalam pelayar, penghurai JSON mencipta objek rentetan JavaScript untuk data Base64.
Apabila aplikasi memerlukan imej, ia memanggil penyahkod Base64, yang mencipta Uint8Array daripada 100 kilobait asal. Untuk beberapa milisaat penyahkodan, kedua-dua objek wujud dalam ingatan. Jika halaman memaparkan sepuluh profil dengan avatar, kosnya didarabkan. Alternatifnya ialah untuk API mengembalikan respons JSON dengan URL yang berasingan untuk setiap sumber avatar, membenarkan pelayar mengendalikan muat turun imej dengan caching aslinya, pemaparan progresif dan pengurusan memori.
Alternatif: berbilang bahagian, URL muat turun berasingan dan titik akhir binari mentah — pertukaran bagi setiap satu
Pertukaran antara memasukkan binari dalam JSON dan mengambilnya secara berasingan bergantung pada tujuan API dan corak penggunaan. Untuk halaman hasil carian yang mengembalikan ratusan imej lakaran kecil kecil, mengambil setiap satu sebagai permintaan berasingan mengalahkan HTTP pengumpulan dan caching sambungan. Memasukkannya sebagai Base64 dalam respons JSON mungkin lebih pantas. Untuk halaman profil terperinci yang meminta satu atau dua imej resolusi tinggi, muat turun berasingan jelas lebih baik. Dokumentasi API harus menyatakan saiz maksimum medan Base64 dan bila pelanggan harus mengharapkan titik akhir yang berasingan.
Jika medan kerap melebihi satu atau dua kilobait, strategi inline-Base64 adalah tanda bahawa reka bentuk API memerlukan pertimbangan semula. Alternatif kepada Base64 dalam JSON wujud tetapi masing-masing mempunyai pertukaran. Berbilang bahagian MIME membalas perduaan dan teks yang berasingan supaya bahagian perduaan dihantar sebagai bait mentah dan sahaja bahagian teks ialah JSON. Ini memerlukan klien untuk menghuraikan mesej berbilang bahagian dan bukannya sahaja memanggil JSON.parse, menambah kerumitan. Muat turun berasingan URL dalam respons JSON menunjukkan pelanggan untuk mengambil sumber binari secara berasingan.
Konvensyen yang patut dinyatakan dalam dokumen API anda — standard berbanding abjad base64url, padding dan saiz maksimum
Ini berfungsi dengan baik apabila sumber binari besar atau kurang kerap diakses daripada metadata. Titik akhir binari mentah yang sahaja mengembalikan bait dan meninggalkan JSON sepenuhnya ialah pendekatan yang paling mudah tetapi mengalih keluar struktur yang JSON menyediakan. Sesetengah API mengembalikan data binari termampat dan pengekodan Base64 itu, mengurangkan penalti saiz tetapi menambah overhed penyahmampatan. Pilihan bergantung pada penggunaan yang dijangkakan: medan kecil adalah sebaris halus, medan besar tergolong dalam sumber yang berasingan dan data berstruktur patut disimpan dalam JSON walaupun dengan kos Base64.
Konvensyen penting untuk saling kendali. API yang mengekod data binari Base64 harus mendokumentasikannya dengan jelas dan menyatakan sama ada abjad itu standard atau URL-selamat. Standard Base64 menggunakan + dan /, yang selamat dalam rentetan JSON tetapi tidak dalam URL. URL-safe Base64 menggantikannya dengan - dan _, yang sesuai untuk data: URI tetapi tidak perlu pelepasan aksara dalam JSON. Dokumentasi harus menentukan sama ada padding disertakan atau ditinggalkan, kerana kedua-duanya adalah Base64 yang sah tetapi pelanggan yang mengharapkan padding dan menerima data unpadded akan gagal secara senyap atau menghasilkan sampah.
Perkara ini tidak meliputi — protobuf, CBOR dan format siri binari lain
Untuk medan yang sangat besar atau kerap dikemas kini, mendokumenkan titik akhir binari yang berasingan adalah penting supaya pelanggan tidak cuba mengambil kilobait data yang tidak diperlukan. Nyahpepijat API dengan medan Base64 adalah mudah dengan alat yang betul. Pengekod & penyahkod Base64 membolehkan anda menyahkod mana-mana medan secara setempat dalam pelayar, tanpa menyimpannya atau menghantarnya ke mana-mana. Salin medan Base64 daripada respons JSON, tampalkannya ke dalam penyahkod dan tekan Nyahkod. Untuk data seperti teks (JSON di dalam Base64, sebagai contoh), output yang dinyahkod muncul serta-merta.
Untuk data binari seperti imej, paparan hex menunjukkan kepada anda bait. Ini membantu mengesahkan bahawa pelayan menghantar apa yang anda harapkan dan penyahkod pelanggan anda berfungsi dengan betul. Jika medan menyahkod kepada data yang tidak dijangka, masalahnya adalah dalam pengekodan pelayan atau dalam cara anda menyalin medan tersebut. Jika ia menyahkod kepada gumpalan separa, medan itu mungkin telah dipotong atau panjang Base64 mungkin salah. Penyahkodan tempatan mempercepatkan penyahpepijatan berbanding dengan menulis medan pada fail dan membuka alat luaran.
Bawa pulang: Base64 dalam JSON ialah kompromi, jadi dokumentasikannya — cara pengekod & penyahkod Base64 membantu anda memeriksa dan mengesahkan medan yang dikodkan secara setempat
Pendekatan praktikal untuk Base64 dalam API adalah kesedaran dan bukannya pengelakan. Base64 ialah cara standard untuk membawa data binari dalam JSON dan ia berfungsi. Fahami bahawa setiap medan Base64 berharga satu pertiga lagi dalam saiz dan beberapa milisaat CPU masa setiap kitaran permintaan-tindak balas. Untuk metadata kritikal kecil seperti token pengesahan (di mana JWT itu sendiri adalah dikodkan Base64), kosnya boleh diabaikan. Untuk lampiran besar, persoalkan sama ada perduaan harus bergerak dalam respons yang sama atau sebagai sumber yang berasingan.
Dokumentasikan skema pengekodan dan saiz maksimum dalam spesifikasi API anda. Apabila memeriksa respons, gunakan pengekod & penyahkod Base64 untuk mengesahkan penyahkodan medan dengan betul dan untuk memahami perkara yang sebenarnya dihantar oleh pelayan. Disiplin itu memastikan pertukaran dapat dilihat dan keputusan itu disengajakan dan bukannya tidak sengaja.