electron-vue无网络环境,读取本地图片/文件展示在页面vue中protocol

注册自定义协议并拦截基于现有协议的请求实现与file同等级的协议

需要实现的是把电脑本地的图片读取显示,直接返回file://浏览器不支持.,net:error

可以用保存并返回base64(直接nodejs的fs读取文件返回文件流/转化为base64通过invoke返回给vue,字符太多,但不需要协议访问),设置electron的自定义协议通过图片的访问(类http,需要显示时加载)

数据库存的差异化短路径

设置electron的自定义协议通过图片的访问,官网示例

https://www.electronjs.org/zh/docs/latest/api/protocol#protocolregisterfileprotocolscheme-handler

1.设置一个自定义的以app为标识的拦截,

当vue端需要获取这个路径的图片时,卸载index.js的protocol.handle('app', 将触发,request返回要访问的url,例(app://books/cover/books_4_cover_image_1768186177917_ueh6f8uxf.jpg)

在这里拆解这个url,转成绝对路径例(J:\MyScript\book-write\front_electron_book\editor_books_app\uploadImage\books\cover),通过net.fetch访问系统并返回promise

复制代码
// 导入Electron核心模块
import { app, shell, BrowserWindow, ipcMain, Notification, protocol, session,net  } from 'electron'
import { join } from 'path'
import path from 'path'
import url from 'url'
import fs from 'fs'

// 设置协议为标准协议 
protocol.registerSchemesAsPrivileged([
  {
    scheme: 'app',
    privileges: {
      standard: true,
      secure: true,
      supportFetchAPI: true
    }
  }
])
// ============ app ready事件处理 ============
app.whenReady().then(() => {

  electronApp.setAppUserModelId('com.electron.bookmanager')
  
  // 设置窗口快捷键
  app.on('browser-window-created', (_, window) => {
    optimizer.watchWindowShortcuts(window)
  })



 //初始化IPC处理器
  setupIpcHandlers(ipcMain)

 
  console.log('创建窗口')
//定义handle,app为标识,每次访问触发,需要返回promise
  protocol.handle('app', (request) => {
    try {
//拼接本地资源路径 
      const filePath = request.url.slice('app://'.length)
      let dirUrl = path.join(initPath('uploadImage'), filePath)
      let abUrl = url.pathToFileURL(dirUrl)
//使用electron自带的net的fetch方法访问系统级操作网络请求,直接返回,版本太老可能没有net支持
  return net.fetch(abUrl.toString())

//不能用net依旧是读文件自己返回promise,data可转成base64
  //     const data = fs.readFileSync(dirUrl)
  //     // 设置正确的 MIME 类型
  //     const ext = path.extname(dirUrl).toLowerCase()
  //     const mime = {
  //       '.jpg': 'image/jpeg',
  //       '.jpeg': 'image/jpeg',
  //       '.png': 'image/png',
  //       '.gif': 'image/gif'
  //     }[ext] || 'application/octet-stream'
  
  //     return new Response(data, {
  //       headers: { 'Content-Type': mime }
  //     })

    } catch (error) {
      console.error('Failed to load file:', error)
      return new Response('Not Found', { status: 404 })
    }
 
  })
  // 其他逻辑
 
 
})

2.修改vue部分的index.html自带的总入口文件meta标签

复制代码
<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>测试</title>
    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
    <meta
      http-equiv="Content-Security-Policy"
    content="default-src 'self' 'unsafe-inline' 
    'unsafe-eval' blob: data: file: app:;
                   img-src 'self' data: blob: file: app: http: https:;
                   style-src 'self' 'unsafe-inline';
                   script-src 'self' 'unsafe-eval' 'unsafe-inline';
                   connect-src 'self' ws: wss: http: https:;
                   font-src 'self' data:;
                   media-src 'self' data: blob:;"/>

                   <!-- content="default-src 'self';
                   script-src 'self';
                    style-src 'self' 
                    'unsafe-inline'; 
                    img-src 'self' data:"
                /> -->
  </head>

  <body>
    <div id="app"></div>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

3.vue前端使用,设置正确的

background-position:0%;

background-size: inherit;

复制代码
 html
  <div class="book-card" v-for="(item, index) in books"  :key="index"
      :style="{backgroundImage:`url(${getImageUrl(item.coverImageUrl)})`}"

      ></div>
js

function getImageUrl(imagePath) {
  console.log(imagePath)

  return  "app://" +  imagePath
}

css
.book-card {
  background: var(--color-theme-second);
  width: 100px;
  height: 120px;
  margin-bottom: 30px;
  color: var(--color-theme-text);
  position: relative;
  background-position:0%;
  background-size: inherit;
}
相关推荐
IT_陈寒2 小时前
SpringBoot 3.x实战:5个高效开发技巧让我减少了40%重复代码
前端·人工智能·后端
noodles10242 小时前
iOS下怎么就找不到好用的新手引导组件呢?还是得自己动手
前端
不务正业的前端学徒2 小时前
vue2/3 watch原理
前端
老前端的功夫2 小时前
TypeScript索引访问类型深度解析:类型系统的动态访问与模式匹配
前端·javascript·ubuntu·架构·typescript·前端框架
不务正业的前端学徒2 小时前
vue2/3响应式原理
前端
不务正业的前端学徒2 小时前
vue2/3computed原理
前端
前端付豪2 小时前
NodeJs 做了什么 Fundamentals Internals
前端·开源·node.js
爱分享的鱼鱼2 小时前
Pinia 数据跨组件共享机制与生命周期详解
前端
张元清2 小时前
大白话讲 React2Shell 漏洞:智能家居的语音助手危机
前端·javascript·react.js