我们相信:世界是美好的,你是我也是。平行空间的世界里面, 不同版本的生活 也在继续...

话说,在传统的 electron 程序中,大量的逻辑是写在 renderer.js 文件中的。但是,后来随着 electron 的版本发展,逐渐出来了一种呼声:就是要将 node 能力从 renderer.js 中分离出来,让 renderer.js 回归传统 js 的功能。这个时候,出现的新概念就是 preload.js

苏南大叔:electron代码,browserWindow的preload.js作用范围是哪里? - electron-browserwindow-preload-js
electron代码,browserWindow的preload.js作用范围是哪里?(图5-1)

本文的测试环境: [email protected] win10 。本文探讨 preload.js browserWindow 中的应用,当然, preload.js webview 中也有使用到,暂时不在本文的讨论范围内。本文主要命题是: preload.js 的作用范围,以及如何区分当前作用的页面。

开题简述

preload.js 并非一个新事物,在苏南大叔的测试中,至少 [email protected] 系列就支持 preload.js 了。只不过,在以前的经验教程中, renderer.js 是更加被推荐的,掩盖了 preload.js 的锋芒。直到 electron@5 系列中,默认在渲染进程中,禁用了 node 能力, preload.js 才被提上日程。

苏南大叔:electron代码,browserWindow的preload.js作用范围是哪里? - preload-js
electron代码,browserWindow的preload.js作用范围是哪里?(图5-2)

对于 electron browserWindow 来说,一个 browserWindow 可以加载一个 preload.js 。而在 browserWindow 里面,实际上是可以进行页面跳转的。那么,问题来了,页面跳转后,这个 preload.js 还生效么? preload.js 里面定义的全局 js 代码,还能执行么?

下面就是苏南大叔的实验代码,主要功能是:使用 electron 打开一个本地页面 index.html ,然后有如下三个分支:

  • 当前页面跳转到 next.html
  • 新开浏览器窗口打开 next.html
  • 新开 browserWindow 打开 next.html

通过这三种方式来测试, preload.js 中的代码,还能否生效。还是否可以执行?

代码概述

main.js ,这里简单加载 preload.js

//...
const mainWindow = new BrowserWindow({
  //...
  webPreferences: {
    preload: path.join(__dirname, 'preload.js'),
    //...
//...

preload.js ,这里简单定义:当页面加载完 preload.js 的时候(优先于页面内所有的 js 代码),做个 console 输出。

window.hello = function(){
    alert("say hello to 苏南大叔")
console.log("preload init")

苏南大叔:electron代码,browserWindow的preload.js作用范围是哪里? - preload-js-demo-code
electron代码,browserWindow的preload.js作用范围是哪里?(图5-3)

index.html next.html next2.html 三者相互链接,简单调用 preload.js 中的函数,看看能否加载到。 next2.html 是通过 target='_blank' 弹出的。

<script>
  hello();
</script>

另外,值得一提的是:如果使用 electron fiddle 来生成这些 html 的话,会有 CSP 规则限制 inline 的代码执行。具体可以参考下面这篇文章:

electron@12 开始的注意事项

electron@12 开始的新参数, contextIsolation: false ,参与了本次实验。在这个实验中,间接的实验了最新的 electron@12 的新参数 contextIsolation 。在 preload.js 中的 console.log 是一直可以执行的。但是,注入到 window 对象的 hello() 函数,却是只能在 contextIsolation: false 下才能被识别。

苏南大叔:electron代码,browserWindow的preload.js作用范围是哪里? - preload-js-demo-code-error
electron代码,browserWindow的preload.js作用范围是哪里?(图5-4)

const mainWindow = new BrowserWindow({