I need to implement a cancel-able client-side HTTP request in Node.js, without using external libraries. I'm giving a Promise
object - cancellationPromise
- which gets rejected when the cancellation is externally requested. This is how I know I may need to call request.abort()
.
The question is, should I be calling request.abort()
only if https.request
is still pending and response
object is not yet available?
Or, should I be calling it even if I already got the response
object and am processing the response data, like in the code below? In which case, will that stop any more response.on('data')
events from coming?
async simpleHttpRequest(url, oauthToken, cancellationPromise) {
let cancelled = null;
let oncancel = null;
cancellationPromise.catch(error => {
cancelled = error; oncancel && oncancel(error) });
try {
const response = await new Promise((resolve, reject) => {
const request = https.request(
url.toString(),
{
method: 'GET',
headers: { 'Authorization': `Bearer ${oauthToken}` }
},
resolve);
oncancel = error => request.abort();
request.on('error', reject);
request.end();
});
if (cancelled) throw cancelled;
// do I need "oncancel = null" here?
// or should I still allow to call request.abort() while fetching the response's data?
// oncancel = null;
try {
// read the response
const chunks = await new Promise((resolve, reject) => {
response.on('error', reject);
const chunks = [];
response.on('data', data => chunks.push(data));
response.on('end', () => resolve(chunks));
});
if (cancelled) throw cancelled;
const data = JSON.parse(chunks.join(''));
return data;
}
finally {
response.resume();
}
}
finally {
oncancel = null;
}
}
We can use the AbortController object and the associated AbortSignal with the Fetch API to make cancelable HTTP requests. Once the AbortSignal is sent, the HTTP request is canceled and won't be sent if the cancellation signal is sent before the HTTP request is done.
The http. createServer() method turns your computer into an HTTP server. The http. createServer() method creates an HTTP Server object. The HTTP Server object can listen to ports on your computer and execute a function, a requestListener, each time a request is made.
No, it is not blocking - hence why the callback is required to handle the asynchronous result. Naturally, if there is a required serialized relationship then the previous requests must complete in order to use the results ..
POST request (web browser) var http = new XMLHttpRequest(); var params = "text=stuff"; http. open("POST", "http://someurl.net:8080", true); http. setRequestHeader("Content-type", "application/x-www-form-urlencoded"); http. setRequestHeader("Content-length", params.
It depends what you want to achieve by aborting a request.
Just a bit of background. HTTP 1 is not able to "cancel" a request it sends it and then waits for the response. You cannot "roll back" the request you did. You need a distributed transaction to do so. (Further reading.) As the MDN developer document states:
The XMLHttpRequest.abort() method aborts the request if it has already been sent. When a request is aborted, its readyState is changed to XMLHttpRequest.UNSENT (0) and the request's status code is set to 0.
Basically you stop the response from being processed by your application. The other application will probably (if you called abort()
after it was sent to it) finish its processing anyways.
From the perspective of the question:
The question is, should I be calling
request.abort()
only ifhttps.request
is still pending and response object is not yet available?
TL.DR.: It only matters from the point of view of your application. As I glance at your code, I think it will work fine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With