XMLHttpRequest not sent if web page location is changed afterwards - javascript

At some point my webpage is changing its location.href, resulting in the browser navigating to another page.
I would like to do a XHR POST request just before changing the page.
I would rather not wait for this XHR request completion, because not receiving 100% of the requests is OK but speed is paramount.
I tried this code, however the XHR request is NOT send by Firefox/Chrome, because of the location.href change right after.
<html>
<head></<head>
<body>
This is page test1.htm<br>
<input type="button" value="Go!" onclick="go();">
<script>
function go() {
xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() { /* Do nothing */ };
xhr.open('POST', '/cgi-bin/hb.exe?action=remoteapppost', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.send('action=remoteapppost&id=TEST');
// ==> this XHR request is NOT sent because of the following line:
location.href = "test2.htm";
}
</script>
</body>
</html>
If I do a breakpoint or move the location.href = "..."; inside the callback, everything is working fine (of course).
Any idea on how to send a XHR request just before leaving a webpage?

You want to use a combination of the beforeunload event and the new navigator.sendBeacon() API that's designed to not block navigation.

Related

Detecting start and stop of xhr request

I'm using a wysiwyg editor called summernote. This editor exists as an iframe within my application.
The editor accepts images and upon inserting an image into the editor, the image automatically starts to upload to my s3 bucked on aws. I've looked at the source code for django-summernote and I can't seem to see any references to ajax, so I'm not sure if it uses that or another technology.
What I do know is that during the upload process, an xhr request in initiated and remains active for the duration of the upload.
As soon as the user drops an image in the editor (and the xhr request starts), I'd like to show a spinner/loading icon so that they are aware that something is happening. I'd like the spinner to disappear once the xhr request has completed.
Is there a way that I can have javascript listen for any xhr requets and fire an event when one starts and when it ends?
Thanks!
Edit: Paul has indicated that I can use these:
var xhr = new XMLHttpRequest();
console.log('UNSENT', xhr.readyState); // readyState will be 0
xhr.open('GET', '/api', true);
console.log('OPENED', xhr.readyState); // readyState will be 1
xhr.onprogress = function () {
console.log('LOADING', xhr.readyState); // readyState will be 3
};
xhr.onload = function () {
console.log('DONE', xhr.readyState); // readyState will be 4
};
xhr.send(null);
Do I need to poll for the XMLHTTPRequest() every second and then check its status or is there a cleaner way to do this?
Thanks!

How do I count the number of characters in a web page?

I am trying to create a web page that opens another web page when you click the "Try It" button, and then counts the number of characters in that webpage. Right now, this web page successfully opens the web page I ask it to open, but the length of the web page in characters is "undefined". I do not want to get rid of the XMLHttpRequest or the line of code below it, because I am planning to expand this webpage to enable it to parse the webpage by certain specific keywords later. Here is the code:
<!DOCTYPE html>
<html>
<body>
<p>Click the button to open a new browser window.</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
window.open("https://www.gutenberg.org/files/1065/1065-h/1065-h.htm");
var req = new XMLHttpRequest();
req.open('GET', 'https://www.gutenberg.org/files/1065/1065-h/1065-h.htm', false);
alert(req.length);
}
</script>
</body>
</html>
Any assistance that anyone can provide me would be greatly appreciated. Have a nice day.
First of all you need a flag header in the remote server that allow your url to make XMLHttpRequests.
Access-Control-Allow-Origin: * or Access-Control-Allow-Origin: yoururl.com
Another problem is that https version has a redirect to http version, then you could have problems if you are executing this from a https site, because of "mixed content" behaviour of client's browsers. Also synchronous XMLHttpRequest (false flag) is deprecated or going to be deprecated soon https://xhr.spec.whatwg.org/ .
If you perform this in the same domain (http gutenberg) it works. You should try executing this in your http server, and looking the console expecting not to have Access-Control-Allow-Origin restriction.
var req = new XMLHttpRequest();
req.open('GET', 'http://www.gutenberg.org/files/1065/1065-h/1065-h.htm', true);
req.onreadystatechange = function (aEvt) {
if (req.readyState == 4) {
if(req.status == 200)
console.log(req.responseText);
else
console.log("Error loading page\n");
}
};
req.send(null)

Chrome Extension interact with page (not in tab) in background

How can I make a extension that interact with a page in background (not in tab)? for example check www.google.com each 5 minutes while I have only www.yahoo.com open.
I have made the function of the extension but I need to know how to use it without having this page open.
Regards.
Saying you want to interact with https://www.google.com without opening it, you could make an ajax call in background page. Steps would be like the following:
Add https://www.google.com/* in permissions field in manifest.json
"permissions": ["https://www.google.com/*"]
Make an ajax call in background page.
var xhr = new XMLHttpRequest();
xhr.onload = function() {
var data = xhr.responseText;
// Your logic to handle response data
};
xhr.open("GET", "https://www.google.com");
xhr.send();

Call to xmlhttprequest from page onload event is not working OK when Back from another page

After going from my page to anther page by pressing a link, and than back to current page, than in call to xmlhttprequest from onload event, The js code of xhr.open and xhr.send is working, but the sever side code called by xhr is not running, and in xhr.onreadystatechange function the xhr.responseText is returning his old value.
In this scenario off comming back from another page, call to xmlhttprequest from document.onreadystatechange event is also not working OK.
The same code works OK when I call it from onload in the first page loading (before going to another page and returning), or when I call it from a button click.
Why the call to xmlhttprequest from onload event is not working OK when Back from another page?
I'm using Chrome.
Here is my code:
<script type="text/javascript">
function CallAJAX() {
xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.onreadystatechange = AJAX_onreadystatechange;
xhr.open("GET", '/MyPage.aspx', true);
xhr.send(null);
}
function AJAX_onreadystatechange() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert('xhr.responseText=' + xhr.responseText);
}
}
window.onload = function () {
//alert is working also after going to link and than back to current page
alert('alert')
//Call to xmlhttprequest from page onload event - is Not working OK - after going to link and than back to current page
CallAJAX();
}
</script>
<!--here is the "link" mentioned in the above comment-->
link
<!--Call to xmlhttprequest from button onclick event - is working OK-->
<input id="Button1" type="button" value="button" onclick="CallAJAX();" />
Update
I found the problem:
In some browsers, and in some circumstances, xhr brought the xhr.responseText
value from browser cache, instead to call server.
Here is the solution:
This problem solved by adding unique query string param to url param of xhr.open. This guaranty that the ajax will avoid using the cache, and always hit the server, because with the unique param, the url is turned to unique in every call to xhr.open.
The unique value is produced by "new Date().getTime()" which returns the number of milliseconds between midnight of January 1, 1970 and now.
This is the solution code:
xhr.open("GET", '/MyPage.aspx?uniqueParamVal=' + new Date().getTime(), true);

How to avoid automatic page reload after XMLHttpRequest call?

I know this is a bit paradoxal because XMLHttpRequest shouldn't be reloading the page, and it's the whole point of it.
Tried in Chrome latest version, Safari on iOS and on an Android. All same result.
I am sending a form through it, with files. Works great, the destination site receive correctly the data, and displays it. Sends back a 200, "OK". (It's facebook)
But then my page reloads automatically. Just like if I submitted the form using HTML form and a submit button. (Which was my original problem)
Here is how I do it, from Javascript
// Get the form element
var formData = new FormData(document.getElementById("photosubmitform"));
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://graph.facebook.com/' + facebookWallId + '/photos', false);
xhr.onload = function(event)
{
var json = xhr.responseText; // Response, yay!
}
xhr.send(formData); // Sending it, will reload the page on success...
Any chance you're triggering this by submitting a form? If you don't return false in the onsubmit handler, the form will still be submitted.
Use event.preventDefault() when observing button click in your form.

Categories

Resources