In my web application, what the user does on the page have to be sent my database, so I have the latest changes saved.
I just call the function with the request here when the user close the page:
window.onbeforeunload = sendData;
But where the problems come up is when I send data every 10 second. I do send my requests sync and not async (or it would not be sent onbeforeunload). The problem is that this adds delays to the user interface when the data is sent every 10 second.
setInterval(sendData,10000);
This is what's getting called:
function sendData(){
var xhr = new XMLHttpRequest();
var localData = datatodatabase;
xhr.open("POST", "handler.php", false);
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhr.send("pack="+datatodatabase);
}
Is it possible to add this inside a Web Worker to make the synchronized requests stop delaying what everything else is going on?
(As I said: I have to use synchronized because of onbeforeunload)
Why don't you make it asynchronous every 10 seconds, but onbeforeunload make it synchronous? Like this:
setInterval(function () {
sendData(true);
}, 10000);
window.onbeforeunload = function () {
sendData(false);
}
function sendData(async) {
// Make the ajax call the specific way based on whether *async* is *true* or *false*
// Probably eventually:
xhr.open("POST", "handler.php", async);
}
Related
I'm new to Javascript and am trying to write a userscript which tracks all Ajax calls made within a specific website and if the reponse status code is not 200, I want to automatically repeat that request.
Also these requests I want to repeat are all POST requests which probably makes it even harder.
I've come so far that I'm tracking all Ajax calls but since it seems to be impossible to capture the formdata sent from the POST requests, I don't know how I could repeat the failed calls.
(function() { // Overriding XMLHttpRequest
var oldXHR = window.XMLHttpRequest;
function newXHR() {
var realXHR = new oldXHR();
realXHR.addEventListener("readystatechange", function() {
console.log("an ajax request was made")
console.log(realXHR.status)
//If the status is not 200, repeat the request with same data etc
}, false);
return realXHR;
}
window.XMLHttpRequest = newXHR;
})();
You can try by calling the same function again
if(realXHR.status !==200){
newXHR();
}
I'm currently sending POST requests to a PHP file of mine via a button with the following function:
function buttonFunction() {
$.post("http://ipaddress/core/file.php",{username:username, password:pword, coins:coins}, function(data) {
// Stuff
});
}
However, I recently found out that if the file process/PHP script is still running (trying to obtain the resulting data/response), and the user refreshes the page, the PHP process would still be running on the server. Also, if the user then decided to click the button again (after refreshing), there would be TWO PHP proccesses running from the same user on the server (that is, if the first one was still running):
Javascript Abort POST Request on Retry/Refresh (HIGH CPU Usage)
However, I came across sending POST data with XMLHttpRequest with Javascript:
Send POST data using XMLHttpRequest
So let's say I send my POST request this way, would it be safe to say when the user refreshes/closes out of the page, the PHP execution ends?
function buttonFunction() {
var http = new XMLHttpRequest();
var url = "get_data.php";
var params = "lorem=ipsum&name=binny";
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
}
However, if this also does not work, how can I fix this issue (multiple scripts running in the background from the same user)? Whether that fix be in the PHP file or in the JavaScript itself, any help would be appreciated.
Edit 1:
Possible Solution?
What if I use XMLHttpRequest and abort the request before the page unloads?
window.onbeforeunload = function(event) {
http.abort();
};
I'm trying to make a very simple script that should keep me logged on a site, that deletes your session after 10 minutes of inactivity. This is quite simple, as follows:
//Silently "refresh" the page - at least server thinks you refreshed, thus you're active
function call() {
var req = new XMLHttpRequest();
//Load current url
req.open("GET",location.href,true);
//Try to only send the data! (does not work - the browser also receives data)
req.onprogress = function() {
this.abort(); //Abort request
wait(); //Wait another 5 minutes
}
//Repeat request instantly if it fails
req.onerror = call;
//Send
req.send();
}
function wait() {
//5minutes timeout
setTimeout(call,5000);
}
wait();
This works perfectly but the requests seem to load completely. Though the page is small, I want to make this clean and prevent downloading the data. This means, I want to stop loading just after the data starts downloading. Or better - after the data has been sent.
Is there a way to make such "ping" function?
I tried this code:
var req = new XMLHttpRequest();
req.onreadystatechange = function(){
console.log( this.readyState );
if( this.readyState == 2 ) { //sent, otherwise it raises an error
console.log( 'aborting...' );
this.abort()
}
if( this.readyState == 4 ) {
console.log( this.responseText );
}
}
req.open( 'get', .... );
req.send();
prints:
1
2
aborting...
3
4
undefined
I am not completely sure with this, but I guess that by aborting the request aborts the download and retrieval of data, but all other states are triggered. I try this with a large image which was not cached and the request was done very quickly, without any result.
BTW. To just send a »ping« to your server you can also set the src of an image tag to the desired script, this will trigger the request too.
I'm using the code below to do a POST request to an API and grab some data from the server
request.open("POST", url, true);
request.setRequestHeader("Content-type", "application/json; charset=UTF8");
request.setRequestHeader("X-Accept", "application/json");
request.send(JSON.stringify(data));
My issue is how to decide if I should do it asynchronous or synchronous. Well actually my issue with async is that I'm not sure how to apply an eventListener which would listen to the completion of that XHR.
If I use asynchronous calls my web application fetches the data too late and the application loads with the previously cache data, though If I use synchronous calls it takes about a second to fetch and display the data and I'm not sure how to display a "loading" icon since I'm not sure where to attach the eventListener.
Could someone make it clear on how to use XHR properly?
I'd like to mention that this is my first time trying to use XHR to fetch data from a server through an API.
Stick with asynchronous, as it doesn't freeze the browser and allows for a more elegant way of dealing with the response. As for the completion of the XHR, use this:
request.open("POST", url, true);
request.onreadystatechange = function () {
if (request.readyState === 4) {
// XHR state is DONE
if (request.status == 200) {
// HTTP 200 status code (success)
// HIDE YOUR "LOADING" SPINNER
// use request.responseText to get the response's content
}
}
};
request.setRequestHeader("Content-type", "application/json; charset=UTF8");
request.setRequestHeader("X-Accept", "application/json");
request.send(JSON.stringify(data));
// SHOW YOUR "LOADING" SPINNER
As always, it's a good idea to read some documentation on it: https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest
"my web application fetches the data too late and the application loads with the previously cache data" - I'm not sure exactly what you mean by that, but if you explain more how your code above is being called/used, I'm sure it could be reorganized to work together properly.
Is it possible to create a Javascript and include it in a web page that the function of this JS is to "catch" all GET request or any other Ajax calls made from any other Javascript on the page? Either to log it or just plain show it in a Alert box.
The "other Javacript" that will be executing GET or Ajax calls is arbitrary. I mean I have no control over that in terms of what it is.
And once caught I need to check which Javascript executing which GET or Ajax calls.
Is this possible?
Try this snippet. It extends the send function so that you can execute something before or after the real sending.
XMLHttpRequest.prototype.reallySend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(body) {
// Do something...
this.reallySend(body);
};
var req = new XMLHttpRequest();
req.open("GET", "any.html", true);
req.send(null);
const nativeOpen = XMLHttpRequest.prototype.open;
const proxiedOpen = function () {
if (arguments[1].includes('youUrl.com')) {
// do some ...
}
nativeOpen.apply(this, arguments);
};
Refer to the answer:
Intercept AND CHANGE the results of an ajax call