electron-vue如何使用webpack打包webview标签中的preload文件

注意:本文基于electron-vue项目(在vue2项目上运行vue add electron-builder命令搭建而成)
并在electron8.5.5及9.0.0测试过

在webview中开发者可以使用preload预加载并执行js文件 官方文档
官方文档
网上以及官方的很多例子都是传入一个相对路径的String,并没有以file://开头。然而我这里只能传入String字符串并且是file协议的,electron会检测是不是以file://开头,不符合就会报错(不知道是不是我配置有问题还是啥…反正只要不以file://开头就必定报错,懂的dalao可以指教一下)
如果只能写file协议的话那必须要有一个单独的preload文件在外面,然后用file协议指向它,即

webPreferences: {
	preload: 'file://xxx/xxx/xxx/preload.js'
}

或者

webPreferences: {
	preload: path.join(__dirname, '../xxx/xxx/preload.js')
}

下面说说三种引入preload的方案

方案一:

我们可以把preload放在public下,然后通过区分生成环境和开发环境并配合使用__dirname传入不同的路径到preload属性(__dirname是指当前文件运行的绝对路径,可以通过require(‘path’)拼接点点斜杠…/来获取上层目录)。
但这里有一个很大的隐患:由于放在public下,webpack并不会处理,只是简单的复制到资源目录,用户拿到应用程序后,preload.js是源码存放在磁盘中,即使在打包后的应用程序依然可以找到preload.js文件,并通过修改它来执行恶意代码。

翻了很多教程之后无果,只能自己想办法了。想到了下面两个相对安全的解决方案

方案二:

使用node的功能创建preload.js文件,然后用file协议指向它,每次执行之前都再创建一次并覆盖之前的preload.js。这样即使用户改了,也会在执行之前还原成我本身的js文件。

这个方案我没有试,感兴趣的可以去试一下,下面重点讲一下我最终使用的方案

方案三:

1.配置打包preload.js文件

使用electron-builder自带的打包preload方案 Vue CLI Plugin Electron Builder官方文档
官方文档
我一开始使用的是1.4.x的electron-builder+8.1.1的electron,使用上述配置无效。后来升级到2.0.0的electron-builder和8.5.5的electron就没问题。

经过上述配置之后,无论是生产环境还是开发环境preload.js文件都是经过webpack处理的,用户无法看到源码,也很难通过修改preload.js来执行恶意代码

接下来就是引入的问题,如果你在主窗口中使用而非webview标签,那么你可以忽略第2点的内容了

2.引入到webview

这里可以用上面提到的方法引入到渲染进程的webview,即通过区分生成环境和开发环境并配合使用__dirname传入不同的路径到preload属性。但不推荐这么做,因为渲染进程的.vue文件,与打包后的preload.js文件的目录可能会因为各种原因发生改变,以致于无法得到正确的路径。

这里我想到了一种较好的办法,既然官方教程是在主进程中使用path.join(__dirname, ‘preload.js’)来指向它,那这个指向肯定不会出错,比自己找相对路径要稳妥很多。既然这样那我把path.join(__dirname, ‘preload.js’)返回的路径字符串传到渲染进程中webview的preload不就行了!马上实验一下,果然可以。

主进程传值给渲染进程可以通过ipc实现,在渲染进程的created钩子中,发送消息给主进程,主进程回应preload的路径即可拿到

又或者使用global共享变量:

// 主进程background.js
function createWindow () {
  global.shareObject = {
    preloadPath: path.join(__dirname, 'preload.js')
  }
  // Create the browser window.
  mainWindow = new BrowserWindow(...)
}


// 渲染进程
<script>
const { remote } = require('electron')
export default {
  data () {
    return {
      preloadPath: ''
	}
  },
  created () {
	this.preloadPath = remote.getGlobal('storage').preloadPath
	// preloadPath赋值到webview的preload中
  }
}
</script>

最近才开始学electron,感觉坑很多教程也很少。每天学习每天进步一点点,这次解决了preload的安全性问题,特此记录一下,也希望能帮到大家

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页