踐:js-base64 純 JS 編解碼庫在 WebSceneAPI 中的集成與使用指南)
移動(dòng)開發(fā)跨平臺(tái)前端UI組件OpenHarmony【免費(fèi)下載鏈接】weexA framework for building Mobile cross-platform UI項(xiàng)目地址https://gitcode.com/gh_mirrors/we/weex點(diǎn)擊查看免費(fèi)下載導(dǎo)讀本文基于 WebSceneAPI 模塊 內(nèi)置的 js-base64 庫位于common/js-base64目錄展開系統(tǒng)講解這一純 JavaScript Base64 編解碼庫的安裝方式、多端導(dǎo)入方法、完整 API 用法與內(nèi)部實(shí)現(xiàn)原理并結(jié)合倉庫源碼揭示它在本項(xiàng)目中如何支撐「Base64 圖片數(shù)據(jù)落盤相冊(cè)」這一真實(shí)業(yè)務(wù)場(chǎng)景。讀完本文你將掌握在 Web 端、Node.js 端以及鴻蒙 ArkTS 工程中正確選用encode/decode、btoa/atob、fromUint8Array/toUint8Array等 API 的完整技能并理解 URL-safe Base64 與 UTF-8 多字節(jié)字符處理的底層細(xì)節(jié)。一、js-base64 是什么定位與倉庫內(nèi)位置js-base64 是一個(gè)用純 JavaScript 實(shí)現(xiàn)的 Base64 轉(zhuǎn)碼器transcoder其 package.json 中自我描述為 Yet another Base64 transcoder in pure-JS采用 BSD-3-Clause 開源協(xié)議倉庫內(nèi)鎖定的版本為3.7.5。在本倉庫的鴻蒙化工程中它作為第三方公共代碼被放置在ohos/web_api_ohos/WebSceneAPI/src/main/ets/common/js-base64/ ├── LICENSE.md # BSD-3-Clause 許可證 ├── README.md # 本文依據(jù)的原始使用文檔 ├── base64.d.ts # TypeScript 類型聲明ArkTS 工程類型檢查依據(jù) ├── base64.js # CommonJS / UMD 版本自動(dòng)生成 ├── base64.mjs # ES Module 版本由 base64.ts 編譯而來 └── package.json # 包元信息與版本號(hào)三個(gè)發(fā)布產(chǎn)物各有分工base64.mjs面向 ES Module 生態(tài)base64.js是面向老環(huán)境的 UMD/CommonJS 版本base64.d.ts提供完整類型聲明——這正是 ArkTS 工程能夠以import { Base64 } from .../js-base64/base64方式獲得類型提示的基礎(chǔ)。二、安裝與引入四種加載方式的完整對(duì)比2.1 npm 安裝在任意支持 Node.js 的工程中一行命令即可安裝$ npm install --save js-base642.2 瀏覽器端傳統(tǒng)script標(biāo)簽本地引入script srcbase64.js/script也可以不經(jīng)過安裝直接通過 CDN 引入base64.min.js構(gòu)建產(chǎn)物。這種傳統(tǒng)方式會(huì)把Base64掛載到全局對(duì)象window上。雖然庫提供了Base64.noConflict()用于恢復(fù)被占用的全局變量但原文檔建議除非必要應(yīng)優(yōu)先使用 ES6 Module 方式避免污染window全局作用域。這一點(diǎn)在 base64.js 的 UMD 包裝代碼中可以得到印證——它檢測(cè)exports/module/defineAMD都不存在時(shí)才把gBase64掛到全局并附帶noConflict方法。2.3 ES6 Module推薦本地安裝后按需導(dǎo)入import { Base64 } from js-base64;如果不希望引入Base64命名空間可以只導(dǎo)入需要的函數(shù)import { encode, decode } from js-base64;也可以直接從 CDN 的base64.mjs文件遠(yuǎn)程導(dǎo)入注意 jsdelivr 對(duì).mjs不做自動(dòng)壓縮。2.4 Node.jsCommonJSconst {Base64} require(js-base64);與瀏覽器全局掛載不同CommonJS 方式不會(huì)修改任何全局對(duì)象。如果習(xí)慣import語法還可以借助esm加載器requirerequire(esm)(module); import {Base64} from js-base64;三、API 速覽一張表看懂全部核心方法下表整理了 base64.d.ts 中聲明的全部公開接口并標(biāo)注了它們?cè)赽ase64.mjs中的實(shí)現(xiàn)位置方法作用參數(shù)源碼位置base64.mjsencode(src, urlsafe?)UTF-8 字符串 → Base64urlsafetrue時(shí)輸出 URL-safe 結(jié)果L123-L125encodeURI(src)等價(jià)于encode(src, true)—L130decode(src)Base64 → UTF-8 字符串兼容普通與 URL-safe 兩種輸入—L208btoa(bin)二進(jìn)制字符串 → Base64同瀏覽器btoa僅接受 Latin-1 字節(jié)—L62-L64atob(asc)Base64 → 二進(jìn)制字符串同瀏覽器atob—L185-L187fromUint8Array(u8a, urlsafe?)Uint8Array→ Base64 字符串urlsafetrue時(shí)輸出 URL-safe 結(jié)果L81toUint8Array(str)Base64 →Uint8Array—L195isValid(src)校驗(yàn)值是否為合法 Base64 字符串非字符串直接返回falseL213-L218extendString()/extendUint8Array()/extendBuiltins()按需擴(kuò)展內(nèi)置原型—L228-L251另有btoaPolyfill、atobPolyfill兩個(gè) polyfill 版本以及標(biāo)注為deprecated、僅供內(nèi)部使用的utobUTF-16 → UTF-8與btouUTF-8 → UTF-16不建議業(yè)務(wù)代碼直接調(diào)用。四、典型用法編碼與解碼的完整示例4.1 編碼方向let latin dankogai; let utf8 小飼弾 let u8s new Uint8Array([100,97,110,107,111,103,97,105]); Base64.encode(latin); // ZGFua29nYWk Base64.encode(latin, true); // ZGFua29nYWk skips padding Base64.encodeURI(latin); // ZGFua29nYWk Base64.btoa(latin); // ZGFua29nYWk Base64.btoa(utf8); // raises exception Base64.fromUint8Array(u8s); // ZGFua29nYWk Base64.fromUint8Array(u8s, true); // ZGFua29nYW which is URI safe Base64.encode(utf8); // 5bCP6aO85by Base64.encode(utf8, true) // 5bCP6aO85by- Base64.encodeURI(utf8); // 5bCP6aO85by-要點(diǎn)解讀encode面向 UTF-8 文本小飼弾這類多字節(jié)字符會(huì)被先轉(zhuǎn)成 UTF-8 字節(jié)序列再編碼所以encode能正確處理非 Latin-1 內(nèi)容而btoa遇到超過 255 的碼點(diǎn)會(huì)拋出TypeError(invalid character found)見 btoaPolyfill 的逐字節(jié)校驗(yàn)邏輯。urlsafe參數(shù)encode(utf8, true)得到5bCP6aO85by-末尾的填充被去掉、變-、/變_這正是 RFC 4648 §5 定義的 URL 與文件名安全字符集。實(shí)現(xiàn)上由_mkUriSafe完成L34-L35。fromUint8Array處理二進(jìn)制當(dāng)數(shù)據(jù)本身是字節(jié)數(shù)組如圖片、文件分片時(shí)用它最合適避免字符串中間轉(zhuǎn)換的性能損耗。4.2 解碼方向Base64.decode( ZGFua29nYWk);// dankogai Base64.decode( ZGFua29nYWk); // dankogai Base64.atob( ZGFua29nYWk);// dankogai Base64.atob( 5bCP6aO85by);// ?°?é£???? which is nonsense Base64.toUint8Array(ZGFua29nYWk);// u8s above Base64.decode( 5bCP6aO85by);// 小飼弾 // note .decodeURI() is unnecessary since it accepts both flavors Base64.decode( 5bCP6aO85by-);// 小飼弾關(guān)鍵差異decode輸出 UTF-8 文本對(duì)5bCP6aO85by解碼得到正確的中文小飼弾。它通過_unURI先把 URL-safe 字符-/_還原為//L202因此同時(shí)兼容普通與 URL-safe 兩種輸入無需單獨(dú)調(diào)用decodeURI。atob輸出原始二進(jìn)制字符串用它解碼5bCP6aO85by得到的是亂碼字節(jié)串?°?é£????——這是正?,F(xiàn)象因?yàn)閍tob不負(fù)責(zé) UTF-8 到文本的還原。toUint8Array還原字節(jié)數(shù)組這是解碼二進(jìn)制數(shù)據(jù)PNG、音視頻的首選入口。4.3 輸入合法性校驗(yàn)Base64.isValid(0); // false: 0 is not string Base64.isValid(); // true: a valid Base64-encoded empty byte Base64.isValid(ZA); // true: a valid Base64-encoded d Base64.isValid(Z A); // true: whitespaces are okay Base64.isValid(ZA); // true: padding s can be omitted Base64.isValid(); // true: can be non URL-safe Base64.isValid(--); // true: or URL-safe Base64.isValid(-); // false: cant mix bothisValid的實(shí)現(xiàn)L213-L218先剔除空白字符與末尾的填充再分別校驗(yàn)「標(biāo)準(zhǔn)字符集」與「URL-safe 字符集」是否純凈——允許整個(gè)輸入都是//風(fēng)格或都是-/_風(fēng)格但不允許混用兩種字符集因此-判定為false。五、內(nèi)置擴(kuò)展按需給原型掛方法默認(rèn)情況下js-base64不會(huì)觸碰任何內(nèi)置原型。需要時(shí)須顯式調(diào)用擴(kuò)展函數(shù)// 擴(kuò)展 String.prototype Base64.extendString(); dankogai.toBase64(); // ZGFua29nYWk 小飼弾.toBase64(); // 5bCP6aO85by 小飼弾.toBase64(true); // 5bCP6aO85by- 小飼弾.toBase64URI(); // 5bCP6aO85by- ab alias of .toBase64(true) 小飼弾.toBase64URL(); // 5bCP6aO85by- an alias of .toBase64URI() ZGFua29nYWk.fromBase64(); // dankogai 5bCP6aO85by.fromBase64(); // 小飼弾 5bCP6aO85by-.fromBase64(); // 小飼弾 5bCP6aO85by-.toUint8Array();// u8s above// 擴(kuò)展 Uint8Array.prototype Base64.extendUint8Array(); u8s.toBase64(); // ZGFua29nYWk u8s.toBase64URI(); // ZGFua29nYWk u8s.toBase64URL(); // ZGFua29nYWk an alias of .toBase64URI()// 一次擴(kuò)展全部 Base64.extendBuiltins()實(shí)現(xiàn)細(xì)節(jié)值得注意extendString與extendUint8Array使用Object.defineProperty且設(shè)置enumerable: false見 L220-L244這樣新增方法不會(huì)出現(xiàn)在for...in枚舉結(jié)果中避免污染常規(guī)遍歷。toBase64URI與toBase64URL是同一函數(shù)的兩個(gè)別名。六、進(jìn)階甄別decode()vsatob()選錯(cuò)會(huì)出大事假設(shè)你需要處理下面這個(gè) Base64 編碼的 1×1 透明 PNGvar pngBase64 iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkYAAAAAYAAjCB0C8AAAAASUVORK5CYII;絕對(duì)不要用Base64.decode(pngBase64)去解碼它。原因Base64.decode()輸出的是UTF-8 字符串——它會(huì)嘗試把解出的字節(jié)按 UTF-8 語義還原成文本二進(jìn)制 PNG 字節(jié)流幾乎必然產(chǎn)生非法 UTF-8 序列結(jié)果被替換或損壞Base64.atob()輸出的是原始字節(jié)字符串與瀏覽器內(nèi)置atob()Node.js 中沒有語義兼容適合還原二進(jìn)制更穩(wěn)妥的做法是Base64.toUint8Array(pngBase64)直接得到可寫入文件、可交給圖像解碼器的Uint8Array。編碼方向同理文本用encode()二進(jìn)制字節(jié)串用btoa()字節(jié)數(shù)組用fromUint8Array()。七、倉庫實(shí)戰(zhàn)在鴻蒙 WebSceneAPI 中把 Base64 圖片落盤相冊(cè)js-base64 在本倉庫并不是擺設(shè)WSMedia.ets 在「保存圖片到相冊(cè)」功能中真實(shí)使用了它。引入方式import { Base64 } from ../../common/js-base64/base64;在saveImg并發(fā)任務(wù)函數(shù)中L89-L114圖片以 Base64 字符串形式傳入處理流程為let uri: string await photoAccessHelper.getPhotoAccessHelper(param.context) .createAsset(photoAccessHelper.PhotoType.IMAGE, png); let imageData: string Base64.atob(param.value); // ① 解碼為原始字節(jié)串 let file: fs.File fs.openSync(uri, fs.OpenMode.WRITE_ONLY); let arrayBuffer: ArrayBuffer new ArrayBuffer(imageData.length); let ia: Uint8Array new Uint8Array(arrayBuffer); for (let i 0; i imageData.length; i) { ia[i] imageData.charCodeAt(i); // ② 字節(jié)串 → ArrayBuffer } fs.writeSync(file.fd, ia.buffer); // ③ 寫入相冊(cè)文件 fs.closeSync(file);這段代碼堪稱上一節(jié)結(jié)論的教科書式應(yīng)用處理圖片這類二進(jìn)制數(shù)據(jù)時(shí)選用Base64.atob()而非Base64.decode()得到逐字節(jié)無損的原始串后手工填充進(jìn)ArrayBuffer再落盤。整個(gè)過程運(yùn)行在Concurrent標(biāo)記的任務(wù)池線程中見 saveImg 定義解碼耗時(shí)不會(huì)阻塞 UI 線程。倉庫還配套了「保存圖片到相冊(cè)」的權(quán)限申請(qǐng)ohos.permission.WRITE_IMAGEVIDEO與失敗回滾邏輯可作為 ArkTS 工程中二進(jìn)制數(shù)據(jù)處理鏈路的完整參考。八、版本演進(jìn)為什么 3.7 特別重要原文檔的 Brief History 記錄了三個(gè)關(guān)鍵節(jié)點(diǎn)結(jié)合 base64.js 與 base64.mjs 的文件形態(tài)可以相互印證3.0 起改用 ES2015 模塊規(guī)范不再兼容 IE 等老瀏覽器3.3 起改用 TypeScript 編寫構(gòu)建流程為base64.ts → base64.mjs → base64.js因此倉庫中的base64.js文件頭部明確標(biāo)注 THIS FILE IS AUTOMATICALLY GENERATED! DO NOT EDIT BY HAND!base64.js3.7 起重新回歸 ES5 兼容進(jìn)而兼容 IE11同時(shí)在本倉庫鎖定的 3.7.5 版本提供了base64.d.ts類型聲明這正是 ArkTS 工程能夠無縫import并使用完整類型提示的前提。九、總結(jié)js-base64 雖然自稱 Yet another Base64 transcoder但憑借純 JS 零依賴、三端瀏覽器/CommonJS/ESM產(chǎn)物齊備、URL-safe 支持、Uint8Array橋接與可選的原型擴(kuò)展等設(shè)計(jì)成為鴻蒙 WebSceneAPI 工程中值得信賴的編解碼底座。實(shí)踐中只需記住三條鐵律文本用encode/decode二進(jìn)制字節(jié)串用btoa/atob字節(jié)數(shù)組用fromUint8Array/toUint8Array處理圖片等二進(jìn)制請(qǐng)遠(yuǎn)離decode()。相關(guān)源碼可在 js-base64 目錄 與 WSMedia.ets 中繼續(xù)深入研讀。贊分享移動(dòng)開發(fā)跨平臺(tái)前端UI組件OpenHarmony【免費(fèi)下載鏈接】weexA framework for building Mobile cross-platform UI項(xiàng)目地址https://gitcode.com/gh_mirrors/we/weex點(diǎn)擊查看免費(fèi)下載相關(guān)推薦如何輕松掌握Base64編碼解碼超實(shí)用的JavaScript庫base64-js完整指南如何輕松掌握Base64編碼解碼超實(shí)用的JavaScript庫base64 js完整指南 在Web開發(fā)和數(shù)據(jù)處理中Base64編碼解碼是一項(xiàng)基礎(chǔ)且常用的技術(shù)開發(fā)工具js-base64JavaScript 中最完整的 Base64 編碼解碼終極指南js base64JavaScript 中最完整的 Base64 編碼解碼終極指南 還在為 JavaScript 中的 Base64 編碼問題而困擾嗎面對(duì)復(fù)序列化js-base64JavaScript 中最完整的 Base64 編碼解碼終極指南 js base64JavaScript 中最完整的 Base64 編碼解碼終極指南 在當(dāng)今Web開發(fā)中Base64編碼解碼是不可或缺的核心技術(shù)而 j序列化上一篇徹底解決fastlane超時(shí)難題從構(gòu)建卡死到精準(zhǔn)控制的實(shí)戰(zhàn)指南下一篇XJoy將任天堂Switch Joy-Con變身高性能PC游戲手柄的終極指南創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考