Send updates about the state of a running HTTP request to the client - node.js

I would like to send updates of a running HTTP request to the client to tell it at what stage the request-triggered process currently is.
The process behind the request does currently the following things (in this order):
Client-side:
Client sends an HTTP Request (upload of a file) to the server
Server-side:
Takes the uploaded file
Encrypt it
Upload it to an archive storage
Return response to the client
(Meanwhile, the client does not know what currently happens)
Client-side:
Get response and show it to the user
I want to tell the client at what stage the process is, like “Uploading done. Encrypting…” and so on.
Is there a way to realize that, or am I missing something? Is it even possible to do?
Frameworks I'm using:
Client: Next.js
Server: Hapi.dev for API development
Thanks

You can send non-final 1xx header responses for your http request as described here.

Related

Why Chrome Refreshes the URL after certain minutes of receiving no response?

In my node application I have an anchor tag which when clicked will request an Express GET route which makes some API calls and render the response in an EJS template.
When the API being requested from Express route takes too long to respond, the Node express route URL gets requested again automatically.
Can anyone explain this behaviour ?
In HTTP/1.1 Connections:
8.2.4 Client Behavior if Server Prematurely Closes Connection:
If an HTTP/1.1 client sends a request which includes a request body,
but which does not include an Expect request-header field with the
"100-continue" expectation, and if the client is not directly
connected to an HTTP/1.1 origin server, and if the client sees the
connection close before receiving any status from the server, the
client SHOULD retry the request
Browsers mostly will re-try a connecton until a proper response is given, on Chrome i believe it's 5 attempts.
It's a expected behavior.
There's a nice article from Oracle's blog that has a similar scenario described.

Why can't I use res.json() twice in one post request?

I've got an chatbot app where I want to send one message e.g. res.json("Hello") from express, then another message later e.g. res.json("How are you doing"), but want to process some code between the two.
My code seems to have some problems with this, because when I delete the first res.json() then the second one works fine and doesn't cause any problems.
Looking in my heroku logs, I get lots of gobbledy gook response from the server, with an IncomingMessage = {}, containing readableState and Server objects when I include both of these res.json() functions.
Any help would be much appreciated.
HTTP is request/response. Client sends a request, server sends ONE response. Your first res.json() is your ONE response. You can't send another response to that same request. If it's just a matter of collecting all the data before sending the one response, you can rethink your code to collect all the data before sending the one response.
But, what you appear to be looking for is "server push" where the server can send data to the client continually whenever it wants to. The usual solution for that is a webSocket connection (or socket.io which is built on top of webSocket and adds more features).
In the webSocket/socket.io architecture, the client makes a connection the server and the connection is kept open indefinitely. Then either side of the connection can send messages to the other end. This is most useful when the server wants to "push" data to the client at any time. In this case, the client establishes the connection, then the server can send data to the client over that connection at any time. The client registers a listener for incoming messages and will be notified anytime the server sends it some data.
Both webSocket and socket.io are fully supported in modern browsers and in node.js. I would personally recommend using socket.io because some of the features it adds (a messaging layer, auto-reconnect, etc...) are very useful.
To use a continuously connected socket like this, you will have to make sure your hosting infrastructure is properly configured to allow it.
res.json() always sends the response to the client immediately (calling it again will cause an error). If you need to gradually build up a response then you can progressively decorate a plain old javascript object; for example, appending items to an array. When you are done call res.json() with the constructed response.
But you should post your code so we can see what's happening.

Is there a way to intercept browser calls in node?

My app was hosted in xxx.com, which gets data from yyy.com. All API requests were triggered from client side.
Is there a way to intercept its request or response in node?
No, and Yes.
For the requests made by your client, you must have some control of the data sent back to the client in order to intercept it.
Assume a scenario where:
Client -----(request)----->Third Party App Server -------(response)-----> Client
In this case, as the back-end server never had a chance to come into picture, there is no way the server can change the data. Well of course, that is when the server doesn't come into picture.
Instead, if you send the request to the node server itself, which forwards the request to the Third Party App server, you obviously have control of the response receive and thus, you can manipulate both request and response or maybe just log it (whatever is your use case).
Client -----(request)----->NODE_SERVER---->Third Party App Server -------(response)-----> Node_Server ----> Client
What a few developers do to intercept the requests made from the client is that they write some client-side JavaScript code and embed it into the browser (Some sort of authentication).
While this works okay in case of normal requests, a person with malicious intents might just disable your front-end interception code and directly receive a response from the Third Party application.
Thus, if you really need to have access to the requests and response,
YOU MUST FORWARD THE REQUESTS TO AN APP SERVER YOU HAVE CONTROL TO.
P.S. It is not just about nodejs.

How can I make socket.io-client in a nodeJS process, reuse an existing HTTP agent for its initial handhsake?

I'd like to be able to create a socket.io-client connection from a NodeJS process reusing an existing HTTP agent (like superagent or request) for the initial handshake. Thus, hopefully sending any relevant cookie with the HTTP request for the handshake.
This behaviour I expect is what already happens when socket.io-client is used in the browser and XHR makes the request for a handshake sending existing cookies for the domain/URL.
Using the same HTTP agent will not solve your problem. By itself, nodejs does not save client cookies.
If you want to save them so they are sent with future client requests, you will have to save and send them yourself or get a module that helps do that for you.
See these other questions for reference:
NodeJS and HTTP Client - Are cookies supported?
How do I create a HTTP Client Request with a cookie?
How to maintain a request session in NodeJS
Can I send a GET request with cookies in the headers in Node?
Making HTTP Requests in Node.js
The request module supports an option for a cookie jar which will remember cookies for you.

How can I abort a request sent using wininet?

I have an MFC application in which I used to send a post request to the corresponding server.
It is an http request, for uploading a file.
But there is a requirement to abort the request sent. Like if the user is sending a large file and user should be able to cancel the request before it is completed.
I am using wininet apis,
HttpSendRequestEx, InternetWriteFile and HttpEndRequest for this.
but once the request is sent, I am not able to abort it in between unless the request is got completed or timed out.
Anyone please suggest an option for canceling a processing or sent request.
I have tried closing the request handles, but still the request not gets aborted.
Any one please help..
Thanks in Advance
From a client aspect, you can only abort/disconnect from the current operation by using the InternetCloseHandle routine.
This will instantly abort the request/operation from a client perspective, so the user can continue with another action.
But when the data has already been sent to the server, this will only result in not getting back a response!
As said by Igor, you cannot abort the processing at the server, as soon as the complete request (data) has been sent (at which point the client just waits to receive data from the server).
So you need to look at the point where you want to cancel 'sending' the request or revert the file addition at the server by sending a new 'delete' request from the client to the server, using the response of the first request (this response should contain information about the added file - like a key).

Categories

Resources