Errors decoding a binary image file using blob & window.btoa in tauri with Vue3

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();

// an arbitrary image in the /img dir in my project
let img_path = "E:/myProjects2/tauri_vue/mdren/img/a-1-01.png";
// convert the image file from Uint8Array to string, then solve it with 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);

// an async logics
currentLogics();

async function currentLogics() {
  try {
    // process the markdown file first
    await solveMd();
    // re-render the images after the DOM has changed
    nextTick(() => {
      reloadImg();
    })
  } catch (e) {
    console.log(e);
  }
}

async function solveMd() {
  md_context.value = await md.render("$\xRightarrow{aaaaaaaaaaaaaaaaaaa}$nn<img id='img-to-remove' src='../img/a-1-01.png'>");
  // ignore the xRightarrow line, the markdown-it-katex cannot stretch it properly, and it's temporarily fixed with other methods
}

async function reloadImg() {
  console.log("function called");
  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>
        <resolveData />
    </Suspense>
</template>

<style scoped>

</style>

I wrote a markdown rendering tool using tauri + Vue3 + markdown-it, but there are images in the markdown files, the contents are binded to the pages with v-html, so all the assets resolved using relative routes.

The images are rendered properly with npm run tauri dev, with a localhost built in the main directory of the project. However with npm run tauri build, this won’t work, the images cannot render mainly due to the security policy.

Then I revised the tauri.conf.json as the ConvertFileSrc shows, setting the tauri.security.csp as "csp": "default-src 'self'; img-src '*' asset: https://asset.localhost", where the '*' is set as other blogs suggests (actually it does not work with 'self' either), and the images still won’t show.

Then I tried to use the Rust backend to read the file and send it to the frontend, using the blob to create a url, however the image seems broken, but the img src in dev tools seemed proper.

Afterwards I tried the tauri/api/fs. First, setting the tauri.allowlist.fs in the tauri.conf.json to:

    "fs": {
        "all": true,
        "scope": ["D:/**", "E:/**"]
    }

which allows it to read all the files in the disks, then set the csp to: "csp": "asset:". The main logics to prosess the image is:

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;
}  // contents: Uint8Array -> string
let src = window.btoa(str_contents);  // window.btoa: string -> url

// ...

// call reloadImg after the DOM has changed, re-render the <img id="img-to-remove" ...>
async function reloadImg() {
  console.log("function called");
  let img_element = document.querySelectorAll("#img-to-remove");
  console.log(img_element);
  img_element.forEach(async (element) => {
    element.src = "data:image/png;base64," + src;
  });
}

which is shown at the beginning of the question. These attempts all worked well except the last step, the img src all seemed correct, but the images are all broken. I guess this problem might be caused with the readBinaryFile and the attempts using the Rust backend to read the file. The csp and rendering all passed my tests.