Same-origin policy

The same-origin policy is the browser rule that a document may only read data from the same origin it was loaded from. An origin is the triple scheme + host + port.

A B Same origin?
https://example.com/a https://example.com/b Yes
https://example.com http://example.com No — scheme
https://example.com https://reports.example.com No — host
http://localhost:3000 http://localhost:8080 No — port
file:///Users/x/a.html file:///Users/x/b.json No — opaque

It is the rule that stops a page you opened from reading your webmail in another tab. Everything below is a consequence of it being unconditional.

The opaque file:// origin

A document opened from disk gets an opaque origin: one that matches nothing, including other files in the same folder. Chrome has treated file:// this way for years; Firefox followed.

So a report that renders a shell and then fetches its results — Allure's data/ tree, Playwright's trace index, several coverage trees — produces a blank page with a CORS error in the console. Nothing is corrupt. The page asked for its own data and the browser refused.

Access to XMLHttpRequest at 'file:///…/data/suites.json' from origin 'null'
has been blocked by CORS policy: Cross origin requests are only supported
for protocol schemes: http, https…

origin 'null' is the tell.

Fixing it locally

Serve the directory instead of opening the file:

cd allure-report && python3 -m http.server 8000   # then http://localhost:8000
allure open allure-report                         # tool-provided server
npx playwright show-report                        # same idea

A real http:// origin makes the fetches legal. This is the entire reason those wrapper commands exist (Allure blank · Playwright blank).

Why it resurfaces when sharing

A local server fixes it for you and nobody else. Emailing the file puts the recipient back on file:// with the same blank page — and localhost links do not work for other people.

Publishing the output directory gives every reader a real HTTPS origin, so the runtime fetches resolve for them exactly as they do behind your local server. The report body runs inside a sandboxed iframe with allow-scripts and no allow-same-origin, which keeps interactivity working without granting the report access to the account around it.

Try it

Comma is free — unlimited reports, unlimited commenters, unlimited revision history.

Publish a report with a real origin →

Related