Saya menggunakan window.atob()
fungsi Javascript untuk mendekode string berenkode base64 (khususnya konten berenkode base64 dari GitHub API). Masalahnya adalah saya mendapatkan kembali karakter yang dikodekan ASCII (seperti â¢
alih - alih ™
). Bagaimana cara saya menangani aliran berenkode base64 dengan benar sehingga diterjemahkan sebagai utf-8?
javascript
encoding
utf-8
brandonscript
sumber
sumber
atob
Jawaban:
Ada artikel bagus di dokumen MDN Mozilla yang menjelaskan dengan tepat masalah ini:
Catatan tentang solusi sebelumnya: artikel MDN awalnya menyarankan penggunaan
unescape
danescape
untuk memecahkanCharacter Out Of Range
masalah pengecualian, tetapi sejak itu sudah tidak digunakan lagi. Beberapa jawaban lain di sini menyarankan untuk mengatasi masalah ini dengandecodeURIComponent
danencodeURIComponent
, ini terbukti tidak dapat diandalkan dan tidak dapat diprediksi. Pembaruan terbaru untuk jawaban ini menggunakan fungsi JavaScript modern untuk meningkatkan kecepatan dan memodernisasi kode.Jika Anda mencoba menghemat waktu, Anda juga dapat mempertimbangkan untuk menggunakan perpustakaan:
Mengenkode UTF8 ⇢ base64
Mendekode base64 ⇢ UTF8
Solusi pra-2018 (berfungsi, dan meskipun mungkin dukungan yang lebih baik untuk browser lama, bukan yang terbaru)
Berikut adalah rekomendasi saat ini, langsung dari MDN, dengan beberapa kompatibilitas TypeScript tambahan melalui @ MA-Maddin:
Solusi asli (tidak digunakan lagi)
Ini bekas
escape
danunescape
(yang sekarang sudah tidak digunakan lagi, meskipun masih berfungsi di semua browser modern):Dan satu hal terakhir: Saya pertama kali mengalami masalah ini saat memanggil GitHub API. Agar ini berfungsi di Safari (Seluler) dengan benar, saya sebenarnya harus menghapus semua ruang putih dari sumber base64 bahkan sebelum saya dapat memecahkan kode sumber. Apakah ini masih relevan atau tidak di tahun 2017, saya tidak tahu:
sumber
b64DecodeUnicode('4pyTIMOgIGxhIG1vZGU=');
sekarang dengan benar menampilkan "✓ mode à la"decodeURIComponent(atob('4pyTIMOgIGxhIG1vZGU=').split('').map(x => '%' + x.charCodeAt(0).toString(16)).join(''))
kode bukanlah kode yang paling berkinerja, tetapi itulah yang terjadi.return String.fromCharCode(parseInt(p1, 16));
agar memiliki kompatibilitas TypeScript.Banyak hal berubah. Metode escape / unescape sudah tidak digunakan lagi.
Anda dapat mengenkode URI string sebelum Anda menyandikannya Base64. Perhatikan bahwa ini tidak menghasilkan UTF8 berenkode Base64, melainkan data berenkode URL berenkode Base64. Kedua belah pihak harus menyetujui pengkodean yang sama.
Lihat contoh yang berfungsi di sini: http://codepen.io/anon/pen/PZgbPW
Untuk masalah OP, pustaka pihak ketiga seperti js-base64 harus menyelesaikan masalah.
sumber
Jika Anda lebih menyukai string sebagai byte, Anda dapat menggunakan fungsi berikut
sumber
Berikut adalah solusi yang diperbarui 2018 seperti yang dijelaskan dalam Sumber Daya Pengembangan Mozilla
UNTUK ENKODE DARI UNICODE KE B64
UNTUK DEKODE DARI B64 KE UNICODE
sumber
Artikel lengkap yang cocok untuk saya: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Base64_encoding_and_decoding
Bagian tempat kami menyandikan dari Unicode / UTF-8 adalah
Ini adalah salah satu metode yang paling banyak digunakan saat ini.
sumber
Saya akan berasumsi bahwa seseorang mungkin menginginkan solusi yang menghasilkan URI base64 yang dapat digunakan secara luas. Silahkan kunjungi
data:text/plain;charset=utf-8;base64,4pi44pi54pi64pi74pi84pi+4pi/
untuk melihat demo (copy data uri, buka tab baru, paste data URI ke address bar, lalu tekan enter untuk menuju halaman). Terlepas dari kenyataan bahwa URI ini dikodekan dengan base64, browser masih dapat mengenali titik kode tinggi dan mendekodekannya dengan benar. Encoder + decoder yang diperkecil adalah 1058 byte (+ Gzip → 589 byte)Di bawah ini adalah kode sumber yang digunakan untuk membuatnya.
Kemudian, untuk mendekode data base64, HTTP dapatkan data tersebut sebagai URI data atau gunakan fungsi di bawah ini.
Keuntungan menjadi lebih standar adalah encoder dan decoder ini lebih dapat diterapkan secara luas karena dapat digunakan sebagai URL valid yang ditampilkan dengan benar. Mengamati.
Selain sangat terstandarisasi, potongan kode di atas juga sangat cepat. Alih-alih rantai suksesi tidak langsung di mana data harus diubah beberapa kali antara berbagai bentuk (seperti dalam tanggapan Riccardo Galli), potongan kode di atas adalah sesingkat mungkin. Ini hanya menggunakan satu
String.prototype.replace
panggilan cepat sederhana untuk memproses data saat encoding, dan hanya satu untuk mendekode data saat mendekode. Kelebihan lainnya adalah (terutama untuk string besar)String.prototype.replace
memungkinkan browser untuk secara otomatis menangani manajemen memori yang mendasari mengubah ukuran string, memimpin peningkatan kinerja yang signifikan terutama di browser yang selalu hijau seperti Chrome dan Firefox yang sangat dioptimalkanString.prototype.replace
. Terakhir, lapisan gula pada kue adalah untuk Anda pengguna skrip latin exclūsīvō, string yang tidak berisi poin kode di atas 0x7f akan diproses lebih cepat karena string tetap tidak dimodifikasi oleh algoritme pengganti.Saya telah membuat repositori github untuk solusi ini di https://github.com/anonyco/BestBase64EncoderDecoder/
sumber
Koreksi kecil, unescape dan escape tidak digunakan lagi, jadi:
sumber
encodeURIComponent
merupakan kebalikan daridecodeURIComponent
, yaitu hanya akan membatalkan konversi. Lihat stackoverflow.com/a/31412163/1534459 untuk penjelasan yang bagus tentang apa yang terjadi denganescape
danunescape
.encodeURIComponent
digunakan, adalah untuk menangani (seluruh rentang) string unicode dengan benar. Jadi misalwindow.btoa(decodeURIComponent(encodeURIComponent('€')))
memberiError: String contains an invalid character
karena sama denganwindow.btoa('€')
danbtoa
tidak bisa menyandikan€
.Berikut beberapa kode bukti masa depan untuk browser yang mungkin kurang
escape/unescape()
. Perhatikan bahwa IE 9 dan yang lebih lama tidak mendukungatob/btoa()
, jadi Anda perlu menggunakan fungsi base64 khusus untuk mereka.Contoh yang lebih komprehensif untuk encoding dan decoding UTF-8 dapat ditemukan di sini: http://jsfiddle.net/47zwb41o/
sumber
termasuk solusi di atas jika masih menghadapi masalah coba seperti di bawah ini, Pertimbangkan kasus di mana escape tidak didukung untuk TS.
untuk csv_content Anda bisa mencoba seperti di bawah ini.
sumber