[BUG] setExtraHTTPHeaders ignores CORS in WebKit/Firefox
Context:
- Playwright Version: [1.29.1]
- Operating System: [Mac OS venture 13.1]
- Node.js version: [v16.15.1]
- Browser: [e.g. All, Chromium, Firefox, WebKit]
- Extra: [any specific details about your environment]
Code Snippet
My code:
test.describe(' E2E test', () => {
test.only('new user', async ({ schedule, page }) => {
await page.setExtraHTTPHeaders({ "X-GAT-apiEnv": "stage" });
`);
})();
Describe the bug
I'm trying to run end-to-end tests on my framework. And I have to define
await page.setExtraHTTPHeaders({ "X-GAT-apiEnv": "stage" }); on my each test as I added above.
My problem is; when I try to run tests against Chromium I'm seeing so many errors when I check the console in the dev tools, and some web elements that need to be shown are not appearing at all.
And these are the some of errors I'm seeing in the console when I check dev tools:
Access to XMLHttpRequest at 'URL' from origin 'URL' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
or
Access to XMLHttpRequest at 'URL' from origin 'URL has been blocked by CORS policy: Request header field x-gat-apienv is not allowed by Access-Control-Allow-Headers in preflight response.
Tests are running quite fine with both Firefox and Webkit, but with Chromium, I can't fix this issue. When I remove that setExtraHTTPHeaders it works fine but we must add it to each test.
Can you share a repro with us which we can run locally? It seems like your server does return different CORS headers based on this request header.
Thank you very much for your response, Max. I sent you an e-mail so I would be glad If you can check.
(over to Max since he received an e-mail!)
Your repro was very helpful, I spotted an inconsistency in our setExtraHTTPHeaders implementation and how they are treating CORS. That's a minimal repro:
it('should consider CORS', async ({ browser, server, browserName }) => {
server.setRoute('/api/v1/test', (req, res) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.end();
});
const context = await browser.newContext({
extraHTTPHeaders: { 'X-MY-HEADER': 'FOOBAR' },
});
const page = await context.newPage();
await page.goto(server.EMPTY_PAGE);
await page.evaluate(async url => fetch(url), server.CROSS_PROCESS_PREFIX + '/api/v1/test');
await context.close();
});
which passes in Firefox/WebKit but fails in Chromium. Will talk with the team later about it.
It's about the following request: https://maps.googleapis.com/maps/api/geocode/json.
As a workaround you can do the following in your config:
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
launchOptions: {
args: ['--disable-web-security'],
}
},
},
Hello Max,
I am glad that the information provided was helpful, as I had recommended using Playwright in my company, and it's become a fantastic tool of mine to use. Thank you, and all the team for your hard work on it and for providing a walkaround to my configuration. My appreciation for your attention to this matter.
Best regards
I notice this ticket was renamed to remove Chromium from the name, i hit this issue on Chrome.
Is anyone able to provide any specific detail as to why chrome is not included in this ticket? Could it have been fixed in some browser version that I don't have?
EDIT: Tried v1.31 of playwright, still hitting this same issue
Hey, just wondering if there were any updates here? I'm also still confused why this ticket was renamed to mis-match the issue description.
I'm surprised more people aren't hitting this using setExtraHTTPHeaders is breaking our tests in Chrome because setExtraHTTPHeaders is removing so many headers.
We've got the disable web security work around in place but this either isn't enough/is breaking other things as we have some web socket stuff that is broken and it only breaks when we setExtraHTTPHeaders.
Firefox is working fine, which is what this ticket used to say before it was removed and renamed away from being a Chromium bug and into a Webkit/Firefox bug where the functionality is working fine?
@Georgegriff Could you please file a separate issue by filling in "Bug Report" template and providing a repro? It could be that your issue is a different one. This will greatly increase the chance of it being fixed, because all browsers are very different.
I can do, but im not sure how much more value I can provider as the original description/title of this ticket 100% accurately represents my issue, see in snippets from the description/original title:

@Georgegriff As I said, s separate issue will help us with prioritization. Also, we need some code we can run that reproduces the issue. A short test that sets headers and goes to some specific url that does not work. Textual description will not help, because it jut guesses at the root problem, while repro helps us investigate.
I'm trying now, i'm able to reproduce it reliably on our internal site setting our header but i wont be able to share that out. I'll do my best and open an issue. I have one in draft just need to reproduce it outside of our code.
new issue with code snippet which reproduces the issue https://github.com/microsoft/playwright/issues/21811
Would it be possible to add a opt-out option for ExtraHTTPHeaders so that we could pass a list of resources that would be excluded from adding custom headers? We can modify our own services to accept custom headers but those are also added for external dependencies like Google Analytics and break CORS for them as well. If we could exclude those links from automatically adding custom header then it would solve the issue.
What I've found is that the setExtraHTTPHeaders() only works for me in chromium (not safari and not Firefox). For neither debug nor otherwise. Not positive that this is the same issue, but we need a fix (or workaround) for this if possible.
launchOptions: {
args: ['--disable-web-security'],
}
nice workaround over , thanks