如何适配OpenHarmony 鸿蒙 PC安装Node环境第三方js-base64库进行Base64 编码/解码
·
欢迎加入开源鸿蒙PC社区: https://harmonypc.csdn.net/
欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper
AtomGit 仓库地址:https://atomgit.com/OpenHarmonyPCDeveloper/ohos_node_vue_ts
1. 环境搭建:
该文完整梳理了ARM64架构鸿蒙PC(HarmonyOS/OpenHarmony6.1及以上),基于CodeArts IDE搭建Vite+Vue前端项目的全流程与疑难解决方案。项目实操中,Vite启动会出现rolldown原生模块权限拒绝报错,根源是鸿蒙系统拦截未签名二进制文件,最终解决方案为引入ohos-signpost自动签名工具,配置npm后置钩子,在依赖安装完成后自动为所有.node文件添加系统合法签名,消除权限校验拦截,最终实现CodeArts IDE内Vue+TS项目正常启动、调试。
js-base64 完整详解 + Vue3 全套 Demo
一、js-base64 是什么
js-base64 是专门处理 Base64 编码/解码 的轻量 npm 库,解决浏览器原生 btoa/atob 的痛点:
- 原生
btoa不支持中文、emoji、特殊Unicode字符,直接转会报错; - js-base64 自动处理 UTF-8 中文、表情符号、特殊符号,开箱即用;
- 支持普通字符串、URL安全Base64、带前缀DataURL、批量转换;
- 同时兼容浏览器 + Node.js 环境。
业务使用场景
- 前端加密传输参数(简单编码,非加密,不能替代AES)
- 图片转base64预览、文件本地存储
- URL参数携带中文(避免URL编码乱码)
- 本地缓存长文本、富文本内容
二、安装
npm install js-base64

三、核心API说明
import { Base64 } from 'js-base64'
// 1. 普通字符串 → Base64(支持中文)
Base64.encode('中文测试123')
// 2. Base64 → 原始字符串
Base64.decode('5Lit5paH5rWL6K+VMTIz')
// 3. URL安全Base64(替换 + / =,适合放地址栏)
Base64.encodeURI('中文测试')
// 4. 判断字符串是否为合法base64
Base64.isValid('xxxx')
// 5. 转DataURL(图片base64格式)
Base64.fromUint8Array(uint8Arr, 'image/png')
原生 btoa 对比(缺陷)
// 原生直接报错:中文无法编码
btoa('中文') // Uncaught DOMException: The string to be encoded contains characters outside of the Latin1 range.
// js-base64 完美兼容
Base64.encode('中文') // "5Lit5paH"
四、Vue3 script setup 完整可运行 Demo
<template>
<div style="padding:24px;max-width:900px;">
<h2>js-base64 编码解码完整演示</h2>
<!-- 输入源文本 -->
<div style="margin:16px 0;">
<h4>原始文本(支持中文/表情/符号)</h4>
<textarea
v-model="sourceText"
rows="4"
style="width:100%;padding:8px;font-size:14px;"
placeholder="输入内容:你好世界 123 !@#$%^&*()"
></textarea>
</div>
<!-- 操作按钮 -->
<div style="display:flex;gap:12px;flex-wrap:wrap;margin-bottom:20px;">
<button @click="encodeNormal">普通Base64编码</button>
<button @click="decodeNormal">Base64解码</button>
<button @click="encodeUrlSafe">URL安全Base64</button>
<button @click="checkValid">校验是否合法Base64</button>
<button @click="copyResult">复制结果</button>
<button @click="clearAll">清空</button>
</div>
<!-- 输出结果 -->
<div style="background:#f7f8fa;padding:14px;border-radius:6px;">
<h4>输出结果:</h4>
<p style="word-break:break-all;white-space:pre-wrap;">{{ result || '暂无输出' }}</p>
</div>
<p style="color:#666;margin-top:8px;">校验状态:{{ validTip }}</p>
<!-- 实战场景1:富文本/长文本缓存 -->
<div style="margin-top:32px;border-top:1px solid #eee;padding-top:20px;">
<h3>实战1:本地存储长文本(localStorage)</h3>
<textarea v-model="article" rows="3" style="width:100%;padding:6px;" placeholder="长篇文章"></textarea>
<div style="margin:8px 0;gap:10px;display:flex;">
<button @click="saveArticle">编码存入本地缓存</button>
<button @click="readArticle">读取并解码展示</button>
</div>
<p>缓存读取内容:{{ cacheText }}</p>
</div>
<!-- 实战场景2:URL传参加密 -->
<div style="margin-top:32px;border-top:1px solid #eee;padding-top:20px;">
<h3>实战2:URL安全编码(路由传中文参数)</h3>
<p>原始参数:{{ urlParam }}</p>
<p>编码后路由参数:{{ urlSafeStr }}</p>
<p>解码还原:{{ decodeUrlStr }}</p>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue'
// 正确导入方式
import { Base64 } from 'js-base64'
// 基础输入输出
const sourceText = ref('你好世界 测试中文123 !@#$%')
const result = ref('')
const validTip = ref('未校验')
// 1. 标准Base64编码
const encodeNormal = () => {
if (!sourceText.value) return alert('请输入内容')
result.value = Base64.encode(sourceText.value)
validTip.value = ''
}
// 2. 解码
const decodeNormal = () => {
if (!sourceText.value) return alert('请输入base64字符串')
try {
result.value = Base64.decode(sourceText.value)
validTip.value = ''
} catch (err) {
result.value = '解码失败,不是合法Base64'
validTip.value = '非法字符串'
}
}
// 3. URL安全编码(去掉+/=,适合路由、请求参数)
const encodeUrlSafe = () => {
if (!sourceText.value) return
result.value = Base64.encodeURI(sourceText.value)
validTip.value = ''
}
// 4. 校验合法性
const checkValid = () => {
if (!sourceText.value) return
const flag = Base64.isValid(sourceText.value)
validTip.value = flag ? '✅ 合法Base64' : '❌ 非法Base64'
}
// 复制结果到剪贴板
const copyResult = async () => {
if (!result.value) return alert('无内容可复制')
await navigator.clipboard.writeText(result.value)
alert('复制成功')
}
// 清空
const clearAll = () => {
sourceText.value = ''
result.value = ''
validTip.value = '未校验'
}
// ========== 实战1:localStorage存储长文本 ==========
const article = ref('这是一段超长富文本内容,包含中文、换行\n特殊符号、表情,直接存容易乱码,用base64编码存储')
const cacheText = ref('')
const STORAGE_KEY = 'article_cache_base64'
// 编码存入缓存
const saveArticle = () => {
const encodeStr = Base64.encode(article.value)
localStorage.setItem(STORAGE_KEY, encodeStr)
alert('保存成功')
}
// 读取解码
const readArticle = () => {
const encodeStr = localStorage.getItem(STORAGE_KEY)
if (!encodeStr) {
cacheText.value = '暂无缓存数据'
return
}
cacheText.value = Base64.decode(encodeStr)
}
// ========== 实战2:路由URL传参 ==========
const urlParam = ref('用户姓名:张三,手机号:13800138000')
const urlSafeStr = ref(Base64.encodeURI(urlParam.value))
const decodeUrlStr = ref(Base64.decode(urlSafeStr.value))
</script>

五、项目通用工具封装 utils/base64.js
全局统一封装,多处组件复用
import { Base64 } from 'js-base64'
/**
* 普通base64编码(支持中文)
* @param {string} str 原始字符串
* @returns string base64
*/
export function base64Encode(str) {
return Base64.encode(str)
}
/**
* base64解码
* @param {string} str base64字符串
* @returns string 原文
*/
export function base64Decode(str) {
try {
return Base64.decode(str)
} catch (err) {
return ''
}
}
/**
* URL安全base64编码(路由/请求参数专用)
*/
export function base64UrlEncode(str) {
return Base64.encodeURI(str)
}
/**
* 校验是否合法base64
*/
export function isBase64(str) {
return Base64.isValid(str)
}
/**
* 对象转base64(接口参数加密传输)
*/
export function objToBase64(obj) {
const jsonStr = JSON.stringify(obj)
return Base64.encode(jsonStr)
}
/**
* base64还原对象
*/
export function base64ToObj(str) {
try {
const json = base64Decode(str)
return JSON.parse(json)
} catch {
return null
}
}

组件调用工具示例
import { base64Encode, base64Decode, objToBase64, base64ToObj } from '@/utils/base64'
// 普通文本
const en = base64Encode('测试中文')
const de = base64Decode(en)
// 对象编码(接口传参)
const user = { name: '李四', age: 22 }
const userCode = objToBase64(user)
const userOrigin = base64ToObj(userCode)
六、main.js 全局挂载(组件无需每次导入)
import { createApp } from 'vue'
import App from './App.vue'
import * as Base64Util from '@/utils/base64'
const app = createApp(App)
app.config.globalProperties.$base64 = Base64Util
app.mount('#app')
组件内使用:
const { proxy } = getCurrentInstance()
const code = proxy.$base64.base64Encode('全局调用测试')

七、对象传输完整业务示例(前后端参数)
import { objToBase64, base64ToObj } from '@/utils/base64'
// 前端:对象编码传给后端
const params = {
id: 1001,
name: '王五',
remark: '备注中文内容'
}
const sendCode = objToBase64(params)
// axios.get('/api/detail', { params: { data: sendCode } })
// 后端返回base64,前端解码还原对象
const resObj = base64ToObj(sendCode)
console.log(resObj.name) // 王五

八、常见坑与注意事项
- 导入不能写错
必须import { Base64 } from 'js-base64',不要写默认导入import Base64 from 'js-base64',会报Base64不是函数。 - Base64 只是编码,不是加密
任何人拿到字符串都能解码,敏感密码不能只用base64,需要搭配AES加密。 - 解码一定要 try catch
传入非法字符串会直接抛出异常,封装工具内部已捕获,业务调用不会报错。 - URL传参必须用
encodeURI
标准base64包含+ / =,URL中会被转义,encodeURI自动替换为安全字符。 - 图片base64超大不推荐本地存储
大图转base64字符串极长,会占用大量缓存,小图标、缩略图适用。


九、和原生 btoa / atob 对比总结
| 方式 | 中文支持 | Emoji | URL兼容 | 推荐场景 |
|---|---|---|---|---|
| btoa/atob | ❌ 报错 | ❌ 报错 | 差 | 纯英文简单场景 |
| js-base64 | ✅ 完美 | ✅ 支持 | 内置url安全方法 | 全业务前端项目 |
更多推荐
所有评论(0)