electron / electron/electron

[Bug]: Unsanboxed preload running after page with content is loaded (ESM)

Open
#40,777 31 comments 5 reactions 0 assignees View on GitHub
bug :beetle: has-repro-comment
Dominant language
C++
Stars
123k
Forks
17.5k
Avg merge
14h 31m
Merged PRs (30d)
858

Description

### Preflight Checklist

- [X] I have read the [Contributing Guidelines](https://github.com/electron/electron/blob/main/CONTRIBUTING.md) for this project.
- [X] I agree to follow the [Code of Conduct](https://github.com/electron/electron/blob/main/CODE_OF_CONDUCT.md) that this project adheres to.
- [X] I have searched the [issue tracker](https://www.github.com/electron/electron/issues) for a bug report that matches the one I want to file, without success.

### Electron Version

28.0.0

### What operating system are you using?

Windows

### Operating System Version

Windows 10 Family

### What arch are you using?

x64

### Last Known Working Electron version

_No response_

### Expected Behavior

Electron 28 added [support for ESM](https://github.com/electron/electron/pull/37535), the new [doc](https://www.electronjs.org/fr/docs/latest/tutorial/esm#unsandboxed-esm-preload-scripts-will-run-after-page-load-on-pages-with-no-content) states that:

> ### Unsandboxed ESM preload scripts will run after page load on pages with no content
>
> If the response body for a renderer's loaded page is completely empty (i.e. `Content-Length: 0`), its preload script will not block the page load, which may result in race conditions.
>
> If this impacts you, change your response body to have something in it (e.g. an empty `html` tag (``)) or swap back to using a CommonJS preload script (`.js` or `.cjs`), which will block the page load.

So for an HTML with content, I expect the preload to be run **before** the page loads:

![image](https://github.com/electron/electron/assets/32762018/cc628ab1-71fd-4db0-84f2-ff47ef34cc28)

### Actual Behavior

For the following HTML:

```html









There is nothing interesting to see here...



```
Loaded as:

```js
new BrowserWindow({
webPreferences: {
nodeIntegration: false,
contextIsolation: true,
sandbox: false,
preload: /*preload path */,
}
});
```

With in `package.json`:

```json
"type": "module"
```
The JS file linked to my HTML shows the page is loaded before the preload.

![image](https://github.com/electron/electron/assets/32762018/ed0761bf-4cf1-4b74-9d72-05be5dfd9bca)

For context, `listen` is a function exposed on the preload with `contextBridge`.

### Testcase Gist URL

_No response_

### Additional Information

I can't see the `Content-Length` header in the response headers:

![image](https://github.com/electron/electron/assets/32762018/668d615e-8de3-4cd2-b50e-674e25af35b3)

The file is loaded from `http://localhost:3000/worker.html`

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.