electron代码,browserWindow的preload.js作用范围是哪里?
发布于 作者:苏南大叔 来源:程序如此灵动~
话说,在传统的electron程序中,大量的逻辑是写在renderer.js文件中的。但是,后来随着electron的版本发展,逐渐出来了一种呼声:就是要将node能力从renderer.js中分离出来,让renderer.js回归传统js的功能。这个时候,出现的新概念就是preload.js。

本文的测试环境:electron@13.0.1,win10。本文探讨preload.js在browserWindow中的应用,当然,preload.js在webview中也有使用到,暂时不在本文的讨论范围内。本文主要命题是:preload.js的作用范围,以及如何区分当前作用的页面。
开题简述
preload.js并非一个新事物,在苏南大叔的测试中,至少electron@3.0系列就支持preload.js了。只不过,在以前的经验教程中,renderer.js是更加被推荐的,掩盖了preload.js的锋芒。直到electron@5系列中,默认在渲染进程中,禁用了node能力,preload.js才被提上日程。

对于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")
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下才能被识别。

const mainWindow = new BrowserWindow({
//...
webPreferences: {
//...
contextIsolation:false
}
})实验结果
实验结果是这样的:只要当前browserWindow还在,无论在其内部的页面地址如何变化,preload.js都是有效的。就相当于:每次页面加载的时候,都自动注入一个公共的js文件。即使是通过target='_blank'打开一个新的electron窗口,preload.js依然有效。

preload.js一次加载,多次执行。新开的窗口,默认也支持preload.js。
这里多说一句,如果你想控制新开
electron窗口的大小的话,可以参考下面这篇文章。
相关链接
- https://newsn.net/say/electron-fiddle.html
- https://newsn.net/say/electron-mirror.html
- https://newsn.net/say/electron-quick-start.html
总结
结论就是:只要browserWindow在,那么preload.js就在,并且页面加载一次,就自动加载preload.js一次。并且其优先级很高,先于页面内原有的js代码。并且,值得一提的是:正常来说,只有preload.js才具有node能力,默认情况下,renderer.js或者是在index.html,都是没有node能力的。除非,你主动赋予他们访问node功能的权利。
下面的链接,是苏南大叔写过的有关electron的相关文章链接,欢迎保存入您的收藏夹中。如下: