Describe the bug
Calling open() on an XMLHttpRequest instance that already has a request in flight does not terminate that request. Both the original and the replacement request keep running concurrently, both dispatch their own load/readystatechange events, and whichever response resolves last silently overwrites status, response, responseText, etc, regardless of which request it belongs to.
In a real browser, calling open() again aborts the previous request (per the "open()" algorithm in the spec, which runs the terminate steps on any existing fetch) so only the replacement request's events fire and its response is the one exposed on the object.
To Reproduce
Steps to reproduce the behavior:
- Create an
XMLHttpRequest, call open() and send() on it.
- Before that request settles, call
open() and send() on the same instance again, targeting a different or slower endpoint.
- Wait for both requests to settle.
- Observe that
load fires twice, and that xhr.status/xhr.response reflect whichever response happened to resolve last rather than the second send() call.
const xhr = new XMLHttpRequest();
xhr.addEventListener('load', () => console.log('load', xhr.status));
xhr.open('GET', '/slow');
xhr.send();
xhr.open('GET', '/fast');
xhr.send();
// Both requests fire "load". Whichever settles last wins, even if it's the
// stale "/slow" request that should have been terminated by the second open().
https://stackblitz.com/edit/happy-dom-dual-load-bug?file=index.js
Expected behavior
Calling open() while a request is in flight should silently terminate the previous request (no abort/error events for it, since it never gets that far per spec) and only the new request initiated by the subsequent send() should be able to dispatch events or write to status/response/etc.
Device and details:
- OS: MacOS 26.6.1
- Node version: 24.19.0
- Package version: 20.11.2
Additional context
Relevant spec section: https://xhr.spec.whatwg.org/#the-open()-method (the "terminate the ongoing fetch" step).
Describe the bug
Calling
open()on anXMLHttpRequestinstance that already has a request in flight does not terminate that request. Both the original and the replacement request keep running concurrently, both dispatch their ownload/readystatechangeevents, and whichever response resolves last silently overwritesstatus,response,responseText, etc, regardless of which request it belongs to.In a real browser, calling
open()again aborts the previous request (per the "open()" algorithm in the spec, which runs the terminate steps on any existing fetch) so only the replacement request's events fire and its response is the one exposed on the object.To Reproduce
Steps to reproduce the behavior:
XMLHttpRequest, callopen()andsend()on it.open()andsend()on the same instance again, targeting a different or slower endpoint.loadfires twice, and thatxhr.status/xhr.responsereflect whichever response happened to resolve last rather than the secondsend()call.https://stackblitz.com/edit/happy-dom-dual-load-bug?file=index.js
Expected behavior
Calling
open()while a request is in flight should silently terminate the previous request (noabort/errorevents for it, since it never gets that far per spec) and only the new request initiated by the subsequentsend()should be able to dispatch events or write tostatus/response/etc.Device and details:
Additional context
Relevant spec section: https://xhr.spec.whatwg.org/#the-open()-method (the "terminate the ongoing fetch" step).