Tauri+Vue3中使用window.btoa解码二进制图片文件异常
问题:Tauri+Vue3+markdown-it打包后图片无法显示
我用Tauri+Vue3+markdown-it开发了一款Markdown渲染工具,通过v-html绑定内容,图片采用相对路径引用。开发环境执行npm run tauri dev时图片能正常渲染,但打包构建(npm run tauri build)后,因安全策略限制图片无法显示。
已尝试的解决方案
按ConvertFileSrc文档修改
tauri.conf.json的tauri.security.csp配置为:"default-src 'self'; img-src '*' asset: https://asset.localhost"图片仍无法显示。
尝试通过Rust后端读取文件并传递至前端,用Blob创建URL,图片显示损坏(开发者工具中src看似正常)。
改用
@tauri-apps/api/fs的readBinaryFile接口:- 配置
tauri.allowlist.fs:"fs": { "all": true, "scope": ["D:/**", "E:/**"] } - 将CSP设置为
"asset:" - 核心处理逻辑:
let img_path = "E:/myProjects2/tauri_vue/mdren/img/a-1-01.png"; const contents = await readBinaryFile(img_path); const str_contents = () => { let binary = ""; let len = contents.byteLength; for (let i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return binary; } let src = window.btoa(str_contents);
DOM更新后调用
reloadImg函数替换img元素的src为"data:image/png;base64," + src,src看似正确,但图片仍显示损坏。我怀疑问题出在readBinaryFile或Rust后端读取文件的环节,CSP与渲染逻辑已验证无问题。- 配置
Demo代码
components/imgDecode.vue
<script setup> import { nextTick, ref } from "vue"; import markdownIt from "markdown-it"; import { invoke, convertFileSrc } from '@tauri-apps/api/tauri'; import { resolve, resourceDir } from '@tauri-apps/api/path'; import { readBinaryFile } from "@tauri-apps/api/fs"; const md = markdownIt(); md.set({ html: true }); const md_context = ref(); // 项目/img目录中的任意图片 let img_path = "E:/myProjects2/tauri_vue/mdren/img/a-1-01.png"; // 将图片文件从Uint8Array转为字符串,再用window.btoa处理 const contents = await readBinaryFile(img_path); const str_contents = () => { let binary = ""; let len = contents.byteLength; for (let i = 0; i < len; i++) { binary += String.fromCharCode(bytes[i]); } return binary; } let src = window.btoa(str_contents); // 异步逻辑 currentLogics(); async function currentLogics() { try { // 先处理Markdown文件 await solveMd(); // DOM变更后重新渲染图片 nextTick(() => { reloadImg(); }) } catch (e) { console.log(e); } } async function solveMd() { md_context.value = await md.render("$\xRightarrow{aaaaaaaaaaaaaaaaaaa}$\n\n<img id='img-to-remove' src='../img/a-1-01.png'>"); // 忽略\xRightarrow行,markdown-it-katex无法正常拉伸,已用其他方法临时修复 } async function reloadImg() { console.log("函数已调用"); let img_element = document.querySelectorAll("#img-to-remove"); console.log(img_element); img_element.forEach(async (element) => { element.src = "data:image/png;base64," + src; }); } </script> <template> <div v-html="md_context"></div> </template> <style scoped> </style>
App.vue
<script setup> import imgDecode from "./components/imgDecode.vue"; </script> <template> <Suspense> <imgDecode /> </Suspense> </template> <style scoped> </style>
内容的提问来源于stack exchange,提问作者TsurumiTei
相关产品推荐
相关产品推荐

