如果渲染進程是通過http協議加載的,webview的preload使用相對路徑也會是http協議,但官方文檔明確指出preload不支持http協議,如果只想加載本地文件強制可強制寫為file協議(原答案鏈接:https://stackoverflow.com/questions/36103547/electron-preload-script-for-webview-not-working?rq=1):
<webview src={'http://example.com'} preload={`file://${__dirname}/preload.js`}/>
但如果渲染進程的頁面加載的是遠程文件,preload加載本地文件是不利於維護的,遍搜全網沒找到答案,考慮在每次渲染進程啟動時webview打開之前將遠程的preload文件緩存到本地,preload就可以采用file協議了,親測有效,代碼如下:
const {remote} = require('electron'); const path = require('path'); const fs = require('fs'); // preload的本地緩存路徑 // 注意,這里必須是remote.app.getPath的路徑,不能為__dirname路徑,__dirname打包后的路徑不可讀寫了 const preloadCachePath = path.join(remote.app.getPath('appData'), './preload/remote.webview.preload.js'); function fetchPreload() { return fetch('./preload/webview.preload.js').then(res => res.text()).then(content => { if (!fs.existsSync(path.dirname(preloadCachePath))) { fs.mkdirSync(path.dirname(preloadCachePath)) } fs.writeFileSync(preloadCachePath, content); console.log('fetch remote webview.preload ready', preloadCachePath); }) } function createWebview() { var webview = document.createElement('webview'); webview.src = url; webview.preload = `file://${preloadCachePath}`; return webview; } // init內開始渲染,並可調用createWebview創建webview fetchPreload().then(init)
需要注意的是preload文件內的require的相對路徑可能(未驗證過)會發生變化