I was wondering if it was possible to make a GET request with javascript, so it can update text without refreshing the page.
If this is possible, how can I make a get request with javascript & get the result/decode it from json?
I tried this from a past question:
function updateButton(){
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "http://xxxx.com/getSpecialSale.php", false);
xmlHttp.send(null);
document.getElementById("dicebutton").innerHTML=xmlHttp.responseText;
}
And, it completely stops the main thread, making the website unresponsive. What is wrong?
Currently you set the async parameter to false, so the request is sent to the server and the browser waits for the response. To make an async request, just pass true as thrid param to open
xmlHttp.open("GET", "http://xxxx.com/getSpecialSale.php", true);
in addition to that, you have to register an callback, which waits for the response (and maybe to handle errors..)
xmlHttp.onload = function (e) {
if (xmlHttp.readyState === 4) {
if (xmlHttp.status === 200) {
console.log(xmlHttp.responseText);
} else {
console.error(xmlHttp.statusText);
}
}
};
xmlHttp.onerror = function (e) {
console.error(xmlHttp.statusText);
};
In addition to that a note from the mozilla docs
Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 /
SeaMonkey 2.27), synchronous requests on the main thread have been
deprecated due to the negative effects to the user experience.
var isAjax=false;
function updateButton(){
if(!isAjax) { //Stops the user making a million requests per minute
isAjax=true;
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "http://xxxx.com/getSpecialSale.php", true);
xmlHttp.send(null);
document.getElementById("dicebutton").innerHTML=xmlHttp.responseText;
isAjax=false;
}
}
OR jQuery...
$("#btnUpdate").click(function(){
$.get("http://xxxx.com/getSpecialSale.php", function(data, status){
$("#dicebutton").html(data);
});
});
If you want to use async you will need some code modifications, ie the stuff that happens after the response completes needs to be in a callback function as follows:
function updateButton(){
var xmlHttp = null;
xmlHttp = new XMLHttpRequest();
xmlHttp.open("GET", "http://xxxx.com/getSpecialSale.php", true);
xmlHttp.onload = function () {
document.getElementById("dicebutton").innerHTML=xmlHttp.responseText;
};
xmlHttp.send(null);
}
Related
I have the following generic Ajax response writer which I recently added some logic to, in order to dynamically parse the results for script objects, and run them when I find them using jQuery.globalEval().
Here is the code:
//Generic Results Writter method for Ajax Calls
function writeAjaxResponse(targetId, response) {
document.getElementById(targetId).innerHTML = response;
try {
var dom = $j(response);
dom.find('script').each( function(){
$j.globalEval(this.text || this.textContent || this.innerHTML || '');
});
} catch (e) {
console.error("Error parsing for script reloads: "+e);
}
}
This solution works very nicely the first time its called. However writeAjaxResponse(targetId, response); is called each time a user loads some dynamic Ajax content. And unfortunately after the first time, the scripts are no longer loaded. To be clear, after the server side generated page is loaded, there are numerous links on the page which the users may click, which invoke this handler for the Ajax response.
No error occurs, and no console.error() is written.. The Ajax data loads as normal, its just that the scripts in the response are no longer loaded.
In debugging, $j.globalEval is still getting called and this.text still has the script content in it, and the data looks correct, but still no joy.
Any light someone could shed on this would be very much appreciated!
Adding main ajax call for GET for reference:
function doAjaxGet(targetId, getUrl, handler) {`
var xmlhttp;
if (window.XMLHttpRequest) {
// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
try {
handler(targetId, xmlhttp.response);
}
catch (err) {
alert("Failed calling handler, detail: " + err + " Got responseText: " + xmlhttp.responseText);
}
}
}
xmlhttp.open("GET", getUrl, true);
xmlhttp.send(null);
}
Having this API:
http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1
How can I write using pure JS request that downloads me different data after button click event?
All I get from this code is the same quote all the time:
function getQuote (cb) {
var xmlhttp = new XMLHttpRequest();
var quoteURL = "http://quotesondesign.com/wp-json/posts?filter[orderby]=rand"
xmlhttp.onreadystatechange = function() {
if (xmlhttp.status == 200 && this.readyState==4) {
cb(this.responseText);
}
};
xmlhttp.open("GET", quoteURL, true);
xmlhttp.send();
}
document.querySelector('button').addEventListener("click", function() {
getQuote(function(quote) {
console.log(quote);
});
})
I tried xmlhttp.abort() and stuff but it didnt want to cooperate.
Thanks in advance!
Your response is being cached by the browser. A common trick to avoid this is to perform a request to
http://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1&r={random_number}
Notice how the r={random_number} will make the URL different each time.
This is a caching problem. Add a timestamp as a query parameter and you should be able to bust the cache.
i wrote some code to get the html source code but it is working only IE8,but not working on mozila and chrome , what is the problem , please give me suggestion.
my code
<script>
function processStateChange() {
statusDiv = document.getElementById("stats");
if (req.readyState == 0) { statusDiv.innerHTML = "UNINITIALIZED"; }
if (req.readyState == 1) { statusDiv.innerHTML = "LOADING"; }
if (req.readyState == 2) { statusDiv.innerHTML = "LOADED"; }
if (req.readyState == 3) { statusDiv.innerHTML = "INTERACTIVE"; }
if (req.readyState == 4) {
statusDiv.innerHTML = "COMPLETE";
statusDiv.innerHTML = req.responseText;
}
}
function GetXmlHttpObject() {
if (window.XMLHttpRequest) { // code for IE7+, Firefox, Chrome, Opera, Safari
return new XMLHttpRequest();
} if (window.ActiveXObject) { // code for IE6, IE5
return new ActiveXObject("Microsoft.XMLHTTP");
} return null;
}
//req = new XMLHttpRequest("Msxml2.XMLHTTP");
req = GetXmlHttpObject();
debugger;
if (req) {
req.onreadystatechange = processStateChange;
req.open("GET", "http://whatismyipaddress.com/", true);
req.send();
}
</script>
i checked to debug the code IE was completely working the loop(req.readystate==4 to finally get the response text) but mozila or chromes are only working loop(req.readystate==2 after abort the loop), what is the problem, please give me some suggestion, using jquery or java script to solve the problem
Thank u
hemanth
Due to the same origin policy restriction you cannot send cross domain AJAX calls. The reason this works in IE is probably that you are using some old dinosaurish version of IE that has some bugs and allows such an AJAX request. But no modern browser will ever allow you to do that.
You can send AJAX requests only to the domain from which originated the page containing the javascript code sending the AJAX request.
There are some workarounds depending on the level of control you have over the remote domain. In your case I guess that you have no control over http://whatismyipaddress.com/. So your only option is to write a server side script on your domain that will serve as a bridge between your domain and the remote domain and then send the AJAX request to your script:
req.open("GET", "/myscript", true);
I am trying to delay an AJAX request so that it is sent out 2-3 seconds after the LAST keyup of an input cell.
So far I have managed to delay the requests, but after 2-3 seconds I get one request sent for every keyup in the field...
How can I make jQuery cancel the first ones and just send the last keyup?
Here's the code so far:
$('#lastname').focus(function(){
$('.terms :input').val(""); //clears other search fields
}).keyup(function(){
caps(this); //another function that capitalizes the field
$type = $(this).attr("id"); // just passing the type of desired search to the php file
setTimeout(function(){ // setting the delay for each keypress
ajaxSearchRequest($type); //runs the ajax request
}, 1000);
});
This code above, waits 1 sec then sends 4-5 AJAX requests depending on keypresses.
I just want one sent after the last keyup
I have found some similar solutions in StackOverflow that use Javascript, but I have not been able to implement them to my project due to my small knowledge of programming.
[SOLVED]
Final working code, thanks to #Dr.Molle:
$('#lastname').focus(function(){
$('.terms :input').val("");
}).keyup(function(){
caps(this);
$type = $(this).attr("id");
window.timer=setTimeout(function(){ // setting the delay for each keypress
ajaxSearchRequest($type); //runs the ajax request
}, 3000);
}).keydown(function(){clearTimeout(window.timer);});
Here's the ajaxSearchRequest code:
function ajaxSearchRequest($type){
var ajaxRequest2; // The variable that makes Ajax possible!
try{
// Opera 8.0+, Firefox, Safari
ajaxRequest2 = new XMLHttpRequest();
}catch (e){
// Internet Explorer Browsers
try{
ajaxRequest2 = new ActiveXObject("Msxml2.XMLHTTP");
}catch (e) {
try{
ajaxRequest2 = new ActiveXObject("Microsoft.XMLHTTP");
}catch (e){
// Something went wrong
alert("Browser error!");
return false;
}
}
}
ajaxRequest2.onreadystatechange = function(){
if(ajaxRequest2.readyState == 4){
$result = ajaxRequest2.responseText;
$('#resultcontainer').html($result);
}}
var searchterm = document.getElementById($type).value;
var queryString ="?searchterm=" + searchterm +"&type=" +$type;
if(searchterm !== ""){
ajaxRequest2.open("GET", "searchrequest.php" +
queryString, true);
ajaxRequest2.send(null);
}
}
store the timeout in a variable, so you will be able to clear recent timeouts:
clearTimeout(window.timer);
window.timer=setTimeout(function(){ // setting the delay for each keypress
ajaxSearchRequest($type); //runs the ajax request
}, 3000);
What you are trying to do is called debouncing.
Here's a jquery plugin by Ben Alman that does the job.
And underscore.js includes this functionality as well.
There's really no need to hack the ajax request system. Just make sure it's called at the right moment.
I like the Molle's answer But I would to further improve the performance
var ajaxRequest2; // The variable that makes Ajax possible!
function getAjaxObject()
{
try{
// Opera 8.0+, Firefox, Safari
ajaxRequest2 = new XMLHttpRequest();
}catch (e){
// Internet Explorer Browsers
try{
ajaxRequest2 = new ActiveXObject("Msxml2.XMLHTTP");
}catch (e) {
try{
ajaxRequest2 = new ActiveXObject("Microsoft.XMLHTTP");
}catch (e){
// Something went wrong
alert("Browser error!");
// return false;
}
}
}
return ajaxRequest2;
}
getAjaxObject();
function ajaxSearchRequest($type){
if(typeof ajaxRequest2 =="undefined" || ajaxRequest2 == false)
{
return;
}
ajaxRequest2.abort();
ajaxRequest2.onreadystatechange = function(){
if(ajaxRequest2.readyState == 4){
$result = ajaxRequest2.responseText;
$('#resultcontainer').html($result);
}}
var searchterm = document.getElementById($type).value;
var queryString ="?searchterm=" + searchterm +"&type=" +$type;
if(searchterm !== ""){
ajaxRequest2.open("GET", "searchrequest.php" +
queryString, true);
ajaxRequest2.send(null);
}
}
This change will abort an on going ajax request and send a fresh request. It is helpful when you
Typed-> waited 4 sec ->request sent ->typed again (response not received) ->waited 4 second->another request fires
function processAjaxStateChangeForRowAdd() {
alert(0);
if (req.readyState == 4) { // Complete
if (req.status == 200) { // OK response
processForRowAdd(req.responseText);
} else {
alert("Problem: " + req.statusText);
}
}
}
This code is working fine for IE, Safari and Firefox, but if I remove the alert, then the code will not work in Firefox, though it still works in IE and Safari.
Can anybody give me suggestion why it not working in Firefox without alert?
EDIT: Code that adds a row:
if (window.XMLHttpRequest && browserVersion.indexOf("Microsoft") == -1 ) {
// code for Firefox, Chrome, Opera, Safari
req = new XMLHttpRequest("");
if (req) {
ajaxProcessed = false;
req.onreadystatechange = processAjaxStateChangeForRowAdd;
req.open("POST", url, true);
req.send();
// alert("1");
}
}
The alert is blocking. What this means is that your script is temporarily suspended (even if it's for a few milliseconds). During this time, your AJAX request completes and your req object is being set. You can add a delay (using setTimeout) to your callback to verify this.
I would suggest you post more of your script so that we can help you set up your callback properly. Alternatively, use a library such as jQuery to set up AJAX calls in a cross-browser manner easily.
EDIT: You need to either declare req as a global variable, or use an anonymous function. The following code demonstrates the first method (using a global variable):
var req;
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
if (req) {
req.onreadystatechange = processAjaxStateChangeForRowAdd;
req.open("POST", url, true);
req.send();
}
}
function processAjaxStateChangeForRowAdd() {
if (req.readyState == 4) { // Complete
if (req.status == 200) { // OK response
processForRowAdd(req.responseText);
} else {
alert("Problem: " + req.statusText);
}
}
}
function getHttp()
{
var xmlhttp;
try
{
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
}
catch(e)
{
try
{
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
catch(e)
{
if(typeof XMLHttpRequest != 'undefiend')
{
xmlhttp = new XMLHttpRequest();
}
}
}
return xmlhttp;
}
can you try this:
if (request.readyState == 4) {
if (request.status == 200) {
var response = request.responseText;
} else
alert("status: " + request.status);
}
You should also check for the readyState , the following code might help
req.onreadystatechange=function()
{
if (req.readyState==4 && req.status==200)
{
processForRowAdd(req.responseText)
}
}
Read this for the different values of readyState