WebGL: Iframes disabled due to Cross-Origin-Embedder-Policy header

When developers click Unity's "Build And Run" button for WebGL, Unity automatically uses its built-in dev web server to serve the app over localhost (i.e. via a URL like http://localhost:{port_number}). In newer versions of Unity (such as 2022.3), this built-in dev web server has an issue where it includes a Cross-Origin-Embedder-Policy HTTP response header that disables cross-origin iframes by default. Since 2D WebView for WebGL is powered by the HTML iframe element, this HTTP header prevents webviews from loading correctly in some cases. I have submitted a bug report to Unity about this issue and will update this article in the future if they address it. In the meantime, 2D WebView now includes logic to detect and handle this issue. Starting in 2D WebView for WebGL v4.7, if 2D WebView detects that iframes are blocked due to the Cross-Origin-Embedder-Policy HTTP header, it does the following:

  • If it detects that the app is served over localhost (e.g. by Unity's dev web server) and is running in a Chromium-based browser (like Google Chrome or Microsoft Edge), then it automatically adds a credentialless attribute to the iframe to allow the iframe to load its URL. A side effect of this workaround is that the credentialless attribute makes it so that the web page loaded in the iframe is unable to use cookies or storage. The credentialless attribute isn't currently supported by non-Chromium browsers (like FireFox or Safari).

  • If it detects that the app is not served over localhost (i.e. it's being hosted on a production server) or is running in a non-Chromium based browser (like FireFox or Safari), then the webview automatically displays an error message that links to this article.

If you encounter this issue and need to run the Unity app in a non-Chromium browser (like FireFox or Safari) during development, then here are a couple of options to achieve that:

  • Unity's built-in dev web server only sends the Cross-Origin-Embedder-Policy HTTP header for HTML files that have the extension ".html". So, one workaround is to change the extension of the app's main HTML file from "index.html" to "index.htm" and then load it from the dev server using that updated extension, like http://localhost:{port_number}/index.htm.

  • Another alternative is to use a different local web server instead of Unity's built-in dev web server. For example, you can serve the static files from the build folder using Express.js.