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;
}
相关推荐
Beginner x_u29 分钟前
链表专题:JS 实现原理与高频算法题总结
javascript·算法·链表
Front思36 分钟前
前端的.hbs
前端
我叫汪枫1 小时前
在后台管理系统中,如何递归和选择保留的思路来过滤菜单
开发语言·javascript·node.js·ecmascript
_.Switch1 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
软件技术NINI1 小时前
webkit简介及工作流程
开发语言·前端·javascript·udp·ecmascript·webkit·yarn
Brendan_0011 小时前
JavaScript的Stomp.over
开发语言·javascript·ecmascript
普通网友1 小时前
ES6模块化、Promise、async、await、EventLoop、API接口案例_export function 与 await
前端·ecmascript·es6
念2341 小时前
f5 shape分析
开发语言·javascript·ecmascript
難釋懷1 小时前
Vue混入
前端·javascript·vue.js
苍穹之跃1 小时前
某量JS逆向
开发语言·javascript·ecmascript