Skip to content

Commit

Permalink
fix: [capricorn86#1631] Set fetch credentials to same-origin for xhr …
Browse files Browse the repository at this point in the history
…when withCredentials is false

To more accurately emulate xhr spec behaviour
https://xhr.spec.whatwg.org/#the-withcredentials-attribute
  • Loading branch information
saitonakamura committed Dec 4, 2024
1 parent d3566f4 commit 01768b6
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 1 deletion.
2 changes: 1 addition & 1 deletion packages/happy-dom/src/xml-http-request/XMLHttpRequest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,7 @@ export default class XMLHttpRequest extends XMLHttpRequestEventTarget {
method,
headers,
signal: this.#abortController.signal,
credentials: this.withCredentials ? 'include' : 'omit'
credentials: this.withCredentials ? 'include' : 'same-origin'
});

this.#readyState = XMLHttpRequestReadyStateEnum.opened;
Expand Down
30 changes: 30 additions & 0 deletions packages/happy-dom/test/xml-http-request/XMLHttpRequest.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,36 @@ describe('XMLHttpRequest', () => {
});
});

it('Sets credentials to same-origin if withCredentials is false to emulate xmlhttprequest behaviour', async () => {
await new Promise((resolve) => {
let requestArgs: { headers: { [name: string]: string } } | null = null;

vi.spyOn(Fetch.prototype, 'send').mockImplementation(async function () {
requestArgs = {
headers: {
Authorization:
this.request.credentials === 'same-origin'
? this.request.headers.get('Authorization')
: undefined
}
};
return <Response>{ headers: <Headers>new Headers() };
});

request.open('GET', REQUEST_URL, true);
expect(request.setRequestHeader('Authorization', 'Basic test')).toBe(true);
request.addEventListener('load', () => {
expect(requestArgs).toEqual({
headers: {
Authorization: 'Basic test'
}
});
resolve(null);
});
request.send();
});
});

it('Does not set forbidden headers.', () => {
request.open('GET', REQUEST_URL, true);
for (const header of FORBIDDEN_REQUEST_HEADERS) {
Expand Down
36 changes: 36 additions & 0 deletions packages/integration-test/test/tests/XMLHttpRequest.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,42 @@ describe('XMLHttpRequest', () => {
});
});

it('Send Authorization header in case of same origin request', async () => {
await new Promise((resolve) => {
const window = new Window({
url: 'http://localhost:3000/'
});
const express = Express();

express.get('/get/json', (req, res) => {
if (req.get('Authorization') === 'Basic test') {
res.sendStatus(200);
} else {
res.sendStatus(401);
}
});

const server = express.listen(3000);
const request = new window.XMLHttpRequest();

request.open('GET', 'http://localhost:3000/get/json', true);

request.setRequestHeader('Authorization', 'Basic test');

request.addEventListener('load', () => {
expect(request.status).toBe(200);
expect(request.statusText).toBe('OK');
expect(request.responseURL).toBe('http://localhost:3000/get/json');

server.close();

resolve(null);
});

request.send();
});
});

it('Can perform a real synchronous XMLHttpRequest request to Github.com', () => {
const window = new Window({
url: 'https://raw.githubusercontent.com/'
Expand Down

0 comments on commit 01768b6

Please sign in to comment.