Ajax Request header keep alive - javascript

I have Ajax request to update the client page if any new data is available to server.I have set the connection 'keep-Alive' So here I am not making new Ajax call every time to check the updated data. I have callback which update the page if any records is available.
Below is my Ajax Request.
xmlRequest.open("post", url, true);
xmlRequest.setRequestHeader("Connection", "Keep-Alive");
xmlRequest.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
xmlRequest.send(some data);
It works fine, but if user refresh the browser then, Ajax does not get the updated data from server.
My concept is not very clear on how the connection type "keep-Alive" works. but it seems when user refresh the browser then Ajax connection lost to the server hence Ajax stopped listing.
I know i can fix this by making new call whenever browser refresh the page. but here i want to understand does it really Ajax keep-Alive lose the connection when browser refresh.

The javascript environment normally gets cleared on page reset, but you can use window.localStorage to persist across refresh and maintain your xmlRequest variable. You should then be able to test client + server side together to see if it is necessary to re-initialize the connection.

Let's first try to understand what does Keep-alive mean it means: the server won't close the Connection after fulfilling the request
So hence your sent the requet to the server, and server sent the response back to your browser, now in that case the request will not closed the server will keep the connection open so for every new request you send to server same requet object will be used.
So when you refresh your page the client/browser lost the connection so I think the best solution is to promot your users do not refresh page like it happen when we making transactions.
If you save your connection object to Browser storage this can not be useable!
Thanks
References:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive
Keep Ajax alive
https://reqbin.com/req/javascript/4sa9kqvu/keep-alive-connection-example#:~:text=Keep%2DAlive%20Connection%20Example%20%5BJavaScript,considered%20persistent%20unless%20declared%20otherwise.

Related

Express not allowing more than one pending request from the same IP?

I'm making a chat application that uses long polling with express (I'm aware websockets are better for this, I just wanted to make something specifically with long polling).
This is the code that the client sends a GET request to when it's waiting for a new chat message:
app.get('/api',(req,res)=>{
listeners.push(res)
})
It pushes the response objects to an array, and once a new chat message is available it calls .send() on the responses. When the client recieves the response, it sends a GET request again, waiting for new messages.
Here's the code for when someone sends a message (simplified)
app.post('/api', (req,res)=>{
listeners.forEach(listener=>{
listener.json(req.body)
})
listeners = []
res.status(200).end()
})
I noticed that when I open two tabs of my site, only the 1st tab's request gets put in the array at first. That makes the 2nd tab not receive the 1st chat message. The 2nd tab's request only gets pushed into the array after the 1st chat message. So when the second chat message is sent it works fine. This means that the 2nd tab is always one request behind.
Here's an example in case that wasn't clear:
Client 1 connects
Client 2 connects
---
Client X sends a message:
Client 1's request 1 receives the message
Client 2's request 1 is still pending
---
Client X sends another message
Client 1's request 2 receives the message
Client 2's request 1 receives the message
---
Client X sends another message
Client 1's request 3 receives the message
Client 2's request 2 receives the message
...
Another thing I noticed is that when I restart the server after client 1 and 2 connect, client 2's request get pushed into the array after the restart.
Could someone explain this behavior? Thanks in advance.
This sounds like the browser is hoping to use a cached request so it waits for a previous request with the exact same URL to see if it can use the cached result rather than firing the same request again.
You can test this hypothesis by adding a unique query parameter to every request as that will disable any attempts at caching since they would all be different URLs.
Or, if these requests are sent using the fetch() api in the browser, you can directly tell that API to not use caching with the cache: 'no-cache' option as in:
const response = await fetch(url, {cache: 'no-cache'});

Connect client socket to a cookie

I am making a chat program.
I am using an Nginx server and NodeJS.
I have setup a websocket via ssl and that works fine.
I have decided to use cookies for authentication.
There are two functions which are crucial:
mconnection.prototype.make_server_https=function(){
console.log('Make server https');
var cthis=this;
var server_https=modules.https.createServer({
key: this.ssl_key,
cert:this.ssl_cert,
ca:this.ssl_ca
},(request,response)=>{
console.log('### CreateServer ###');
console.log('CreateServer, Request:');
console.log(request);
console.log('CreateServer, Response:');
console.log(response);
console.log('######');
and
mconnection.prototype.make_server_websocket=function(){
var server_websocket=new modules.ws.Server({server:this.server_https});
var cookie = require("cookie");
var cthis=this;
//whenever a new client connects with the server.
server_websocket.on('connection', function(client_socket, request){
console.log('### On Connection ###');
console.log('OnConnection, Client Socket:');
console.log(client_socket);
console.log('OnConnection, Request:');
console.log(request);
console.log('######');
If I do state the port number in the client url,function make_server_https gets run and inside there i can access the cookie and set it via the response object.
but in the original url,function make_server_websocket gets run, and there i have access to the client_socket on the server. But there it seems i dont have access to the cookies.
I need to client_websocket to start the connection with this given client. And I need to tie it somehow with the cookies login information.
But i never have both at the same time so i dont get how i could connect them to make the login happen.
I am probably misunderstanding something, any help in the right direction would really be appreciated.
you have to serve you index page from node server using GET then when the request reaches backend you will have response object which can then be used to SET-COOKIE if not set from backend.
And after GET request is complete COOKIE will be added in browser, when next request is made for websocket connection COOKIE will be added to the request in REQUEST HEADERS by the browser which will be available in backend through request object.
And if you decide to use it in login system then you can SET-COOKIE on successfull login.
i got it. its an event called on headers, not on connection. and there i can just push onto the headers.

Ignore response from a PUT call - javascript

I've a JS (Angular) client that makes a PUT request (REST API) to server and server sends back a large payload that I'm not using in the client currently.
Is there a way to just fire the request and ignore any response that comes back? The main need here is to avoid the data cost incurred by receiving that payload. I've looked at closing the connection once the request is fired, but am not sure if that's the best way to handle this.
If able, I think the only way to change this would be to change the api endpoint to not include a payload from the put request.
I'm assuming you are using angular's http class and using Observables. But even if you aren't, your angular client is going to need to read the response status sent back from the server to determine whether or not the put request was successful or not. In order to read the status, you'll need to response, and unfortunately the full response sent from the server.
You could close the connection right after the request, but as I've mentioned you'll have no way of knowing whether or not the request was successful.
To ignore the request just don't do anything if the request is successful.
If you don't want the request to exist at all then do it on the backend.

Provide Last-Event-Id to EventSource constructor

Is it possible to set the Last-Event-Id header of an EventSource ? I have a simple chat app that keeps the messages cached. When I connect, I send all the chat since the Last-Event-Id, or all of them if it is not provided.
Since I keep the messages, I figured I might be able to pass the Id to the EventSource constructor to avoid it giving me back all the messages I already have. Is that simply not possible ?
You can pass information on the query string.
var source = EventSource("source?eventId=12345");
Ultimately it is just up to you to make sense of it on the server side and return the correct event(s).
The EventSource request will only have the Last-Event-Id header if the connection breaks and the client will have to reconnect. You can "force" this reconnection by letting the server break the first connection.
It goes like this:
Create a connection using EventSource.
The server receives the request and test if the Last-Event-Id is a request header.
If the Last-Event-Id is present:
get the value/id.
send events from the server according to the id.
If the Last-Event-Id is not present:
send an event containing an id (the id that you consider to be the last id).
make the server break/finish the connection.
If the connection is broken by the server the client will try to reconnect with a new request. This time the request will have a Last-Event-Id header, and now you jump up to number 2.
The only problem with this approach is the delay caused by the client because it has to make two connections. I haven't tested the delay, but it looks like something around 3-5 seconds between each request.

Is it safe to invoke a AJAX call and let the browser cancel the request?

If I make a AJAX reqeust it will be displayed in the network tab in Chrome. If I in the same moment makes a client based redirect, the AJAX request will canceled. But will the request make it to the server and execute as normal? Is it something in HTTP/TCP that know's that the client has canceled the request? I don't think so, but I want to be sure.
If you're running PHP server-side, it will stop processing in the event of a client-side abort. (From what I've read, this isn't the case with other server-side technologies, which will continue processing after a client aborts.) See:
http://php.net/manual/en/features.connection-handling.php
But, it's best not to assume anything one way or another. The browser may cancel the request. And this cancellation may occur in time to stop processing server-side. But, that's not necessarily the case. The client could cancel at any stage during the request -- from right before the request is actually sent to just after a response body is sent. Also bear in mind, there are other things which can interrupt server-side request processing (hardware, power, OS failure, etc.). Expect some unpredictability.
From this, I'd make two recommendations:
Write your code be as transaction-safe as possible. If a request makes data changes, don't commit them until all changes have been piped to the database. And if your application relies on multiple AJAX requests to change some data, don't commit any of the changes until the the end of "final" AJAX request.
Do not assume, even if a request finishes, that the client receives the response. Off the top of my head, that means if your application is AJAX-heavy, always rely on client-side state to tell the server what information it has, rather than relying on server-side state to assume the client "knows" something.
This is one of the few cases where synchronous requests (async: false in the $.ajax(...) options) are appropriate. This usually avoids the browser from navigating to the other page until the request has finished.

Categories