My app have some jquery http calls and some angular http calls....
So.. to add a param to every request, I add this code at the beginning of my code.
var op = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function() {
this.addEventListener("readystatechange", function() {
if(this.readyState === 4 && this.status === 200 ){
// http call is done
}
}, false);
arguments[1] = arguments[1]+'?test=testParam';
var resp = op.apply(this, arguments);
return resp;
};
Now I want 2 things
1) I want to change the response before apply it
2) If the response is 404.... I want to make another call.... take the response... and then repeat the call with some new params
The short answer is that we can't extend XMLHttpRequest to retry the connection because we can't fire .open if we have the .onload event fired. Writing several .open of the same XMLHttpRequest instance causes that each .open rewrites the previously .open, but once .onload event is fired, we can't reuse that instance (the request doesn't send), so we have to create another instance of XMLHttpRequest. So the closest approach in my opinion is reusing the code, like this:
var param = 106;
var div = document.getElementById("retry");
var div2 = document.getElementById("success");
var div3 = document.getElementById("response");
div.innerHTML = "Trying: " + param;
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/' + param);
xhr.onload = function() {
if (this.status === 200) { //<-- we use this instead of xhr
div2.innerHTML = "Success: " + param;
div3.innerHTML = this.responseText;
} else {
var newXhr = xhr; //<-- we have to create another instance
newXhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/' + param);
newXhr.onload = xhr.onload; //<--we reuse the function
newXhr.send();
div.innerHTML = "Trying: " + param;
param--;
}
};
xhr.send();
<div id="retry">
</div>
<div id="success">
</div>
<div id="response">
</div>
This is another approach (my previous answer), that I think is better:
function myAjax(param) {
var div = document.getElementById("retry");
var div2 = document.getElementById("success");
var div3 = document.getElementById("response");
div.innerHTML = "Trying: " + param;
console.log(param);
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://jsonplaceholder.typicode.com/posts/' + param);
xhr.onload = function() {
if (xhr.status === 200) {
div2.innerHTML = "Success: " + param;
div3.innerHTML = xhr.responseText;
} else {
param--;
myAjax(param); //I'm calling again the function
}
};
xhr.send();
}
myAjax(105);
<div id="retry">
</div>
<div id="success">
</div>
<div id="response">
</div>
Related
G'morning folks,
I just have a small problem to fix this issue:
I have a page which should GET some data from a url when opening and the display in the own content. But the GET url contains Parameters from my url.
So:
1. Get Parameters from my URL like www.mydomain.com?test=1&test1=bla
2. open GET with this parameters (1 and bla) and display result
Here my current version:
<body>
<h3>Visa Informationen</h3>
<p id="data"></p>
<script>
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
document.getElementById("data").innerHTML = myObj.response.visa.content;
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
</script>
<script>
function getURLParameter(name) {
var value = decodeURIComponent((RegExp(name + '=' + '(.+?)(&|$)').exec(location.search) || [, ""])[1]);
return (value !== 'null') ? value : false;
}
var param = getURLParameter('test');
if (param) document.getElementById("testnr").innerHTML = param;
var param1 = getURLParameter('test1');
if (param1) document.getElementById("testnr1").innerHTML = param1;
var url = "https://api01.otherdomain.com?test=" + param + "&test1" + param1 + "&trv=0&vis=1"
</script>
</body>
Any hint where the problem is with this code?
Kind regards,
Chris
It seems like you having issue with script execution order.
I assume that testnr element coming from your XML ajax request.
You have two script block in your HTML and it will executed while page load.
When second script block is running your fist XMLHttpRequest not completed so it not able to find given HTML tag document.getElementById("testnr").innerHTML
To overcome this issue you need to execute script only after XMLHttpRequest request is completed.
In your case :
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
document.getElementById("data").innerHTML = myObj.response.visa.content;
// Execute new created function here
SetValues();
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
function getURLParameter(name) {
var value = decodeURIComponent((RegExp(name + '=' + '(.+?)(&|$)').exec(location.search) || [, ""])[1]);
return (value !== 'null') ? value : false;
}
function SetValues()
{
var param = getURLParameter('test');
if (param) document.getElementById("testnr").innerHTML = param;
var param1 = getURLParameter('test1');
if (param1) document.getElementById("testnr1").innerHTML = param1;
var url = "https://api01.otherdomain.com?test=" + param + "&test1" + param1 + "&trv=0&vis=1"
}
</script>
Okay, i fixed the matter.
Here my result which works fine for me:
<script>
function getURLParameter(name) {
var value = decodeURIComponent((RegExp(name + '=' + '(.+?)(&|$)').exec(location.search) || [, ""])[1]);
return (value !== 'null') ? value : false;
}
var param = getURLParameter('test');
var param1 = getURLParameter('test1');
var url = "https://api01.otherdomain.com?test=" + param + "&test1" + param1 + "&trv=0&vis=1"
</script>
<script>
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
var myObj = JSON.parse(this.responseText);
document.getElementById("additionalContent").innerHTML = myObj.response.additionalContent;
document.getElementById("data").innerHTML = myObj.response.visa.content;
}
};
xmlhttp.open("GET", url, true);
xmlhttp.send();
</script>
I am trying to make an XMLHttpRequest, however, I am having issues. The page keeps refreshing automatically even when returning false or using e.preventDefault(). I'm trying to get cities to eventually pass through an options block. (I've started the option section and will complete it after I figure out the get request issue.) I'm trying to do this using pure Javascript because I've already done it using Angular and Node. Any help would be appreciated.
HTML:
<form id="citySearchForm" method="get" onSubmit="return searchFormFunc();">
<div>
<p>Choose a city:</p>
<input type="text" placeholder="Enter a city" id="getCitiesInput" name="city">
<input type="submit" value="submit">
</div>
<div id="weather"></div
<p><span id="temp"></span></p
<p><span id="wind"></span></p>
</form>
Javascript:
var citySearch = document.getElementById("citySearchForm");
// citySearch.addEventListener("submit", searchFormFunc);
function searchFormFunc(e){
cityName = document.getElementById('getCitiesInput').value;
var searchCityLink = "http://autocomplete.wunderground.com/aq?query=";
var search = searchCityLink.concat(cityName);
console.log("link : " + search);
var xhr = XMLHttpRequest();
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
var r = JSON.parse(xhr.response || xhr.responseText); // IE9 has no property response, so you have to use responseText
console.log(r);
} else {
console.log('error');
}
};
xhr.open("GET", link, true);
xhr.send(null);
var r = JSON.parse(xhr.response);
return false;
// e.preventDefault();
}
You are specifying that you want this to be an async request. So you need to parse your response inside of the onreadystatechange or onload.
function ajax(url, callback) {
var xhr;
if(typeof XMLHttpRequest !== 'undefined') xhr = new XMLHttpRequest();
else {
var versions = ["MSXML2.XmlHttp.5.0",
"MSXML2.XmlHttp.4.0",
"MSXML2.XmlHttp.3.0",
"MSXML2.XmlHttp.2.0",
"Microsoft.XmlHttp"]
for(var i = 0, len = versions.length; i < len; i++) {
try {
xhr = new ActiveXObject(versions[i]);
break;
}
catch(e){}
} // end for
}
/** Here you can specify what should be done **/
xhr.onreadystatechange = function() {
if(xhr.readyState < 4) {
return;
}
if(xhr.status !== 200) {
return;
}
// all is well
if(xhr.readyState === 4) {
callback(xhr);
}
}
xhr.open('GET', url, true);
xhr.send('');
}
Answer from documentation by user6123921
You have to use var xhr = new XMLHttpRequest();
you have to define an onreadystatechange event listener
xhr.onreadystatechange = function() {
if(xhr.readyState == 4) {
var r = JSON.parse(xhr.response || xhr.responseText); // IE9 has no property response, so you have to use responseText
console.log(r);
/* do stuff with response */
}
};
I want to show a random quote when a button is clicked. The project is here https://skidle.github.io/projects/random-quote. If you open a console, you can see that this onclick=newQuote() function is working because it generates an JSON object into a console. But the quote stays the same, so should I change the URL somehow?
JS:
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1");
xhr.send();
xhr.onreadystatechange = function () {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
var json = JSON.parse(xhr.responseText);
var elQuote = document.getElementById("quote");
elQuote.innerHTML = json[0]["content"];
var elAuthor = document.getElementById("author");
elAuthor.innerHTML = json[0]["title"];
console.log(json[0]);
} else {
console.log("Error: " + xhr.status); // An error occurred during the request.
}
};
}
var newQuote = function() {
//the script below is the same as above just inserted inside newQuote()
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1");
xhr.send();
xhr.onreadystatechange = function () {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
var json = JSON.parse(xhr.responseText);
var elQuote = document.getElementById("quote");
elQuote.innerHTML = json[0]["content"];
var elAuthor = document.getElementById("author");
elAuthor.innerHTML = json[0]["title"];
console.log(json[0]);
} else {
console.log("Error: " + xhr.status); // An error occurred during the request.
}
};
}
}
HTML:
<main>
<div class="container">
<div class="wrapper">
<section id="quote">
</section>
<div class="button-wrapper">
<button>Tweet this</button>
<div id="author"></div>
<button onclick="newQuote()">New quote</button>
</div>
</div>
</div>
</main>
Thank you in advance!
I think that the ajax request is beeing cached. Try adding a timestamp to the url, like this:
xhr.open("GET", "https://quotesondesign.com/wp-json/posts?filter[orderby]=rand&filter[posts_per_page]=1×tamp="+new Date());
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
Background: I am attempting to retrieve data, using AJAX, and assign it to a variable. I have tried to set the AJAX request to synchronous, but Firefox will not allow it.
Question: How can I make certain all the data is received?
function search(){
var data = [];
this.init = function(){
data = getData({"url":"/imglib/Inventory/cache/2335/VehInv.js"});
console.log(data); // Returns as 'undefined'. Possibly because of asynchronous call?
};
var d = new Date();
function getData(url){
var xhttp: new XMLHttpRequest();
var dataURL = url + '?v=' String(d.getTime());
xhttp.onreadystatechange = function(){
if(this.readyState = 4 && this.status == 200){
var r = this.responseText;
var s = r.indexOf('[') + 1;
var e = r.indexOf(']');
var jsonData = JSON.parse("[" + r.slice(s,e) + "]");
return jsonData;
}
};
xhttp.open("GET", dataURL, true);
xhttp.send();
}
};
you have to use a callback when working with asynchronous stuff..
function search(){
this.init = function(){
getData("http://www.petesrvvt.com/imglib/Inventory/cache/2335/VehInv.js", function(data){
console.log(data); // Returns as 'undefined'. Possibly because of asynchronous call?
});
};
var d = new Date();
function getData(url, callback){
var xhttp: new XMLHttpRequest();
var dataURL = url + '?v=' String(d.getTime());
xhttp.onreadystatechange = function(){
if(this.readyState = 4 && this.status == 200){
var r = this.responseText;
var s = r.indexOf('[') + 1;
var e = r.indexOf(']');
var jsonData = JSON.parse("[" + r.slice(s,e) + "]");
callback(jsonData);
}
};
xhttp.open("GET", dataURL, true);
xhttp.send();
}
};
Call the function that will deal with the data from the function invoked on "onreadystatechange". The reason it doesn't work is that the variable "data" isn't defined with the result of the async query when you are attempting to use it.
(function search() {
var data = [];
this.init = function() {
data = getData({
"url": "http://www.petesrvvt.com/imglib/Inventory/cache/2335/VehInv.js"
});
// This is definitely caused by the asynchronous XMLHttpRequest
//console.log(data); // This needs to be moved to the callback that is invoked when the request completes. See below
};
var d = new Date();
function getData(url) {
var xhttp: new XMLHttpRequest();
var dataURL = url + '?v='
String(d.getTime());
xhttp.onreadystatechange = function() {
if (this.readyState = 4 && this.status == 200) {
var r = this.responseText;
var s = r.indexOf('[') + 1;
var e = r.indexOf(']');
var jsonData = JSON.parse("[" + r.slice(s, e) + "]");
// This is how you be sure you get your data
console.log(jsonData);
}
};
xhttp.open("GET", dataURL, true);
xhttp.send();
}
})();
I would like to search a xhr.responseText for a div with an id like "something" and then remove all the content from the xhr.responseText contained within that div.
Here is my xhr code:
function getSource(source) {
var url = source[0];
var date = source[1];
/****DEALS WITH CORS****/
var cors_api_host = 'cors-anywhere.herokuapp.com';
var cors_api_url = 'https://' + cors_api_host + '/';
var slice = [].slice;
var origin = self.location.protocol + '//' + self.location.host;
var open = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function () {
var args = slice.call(arguments);
var targetOrigin = /^https?:\/\/([^\/]+)/i.exec(args[1]);
if (targetOrigin && targetOrigin[0].toLowerCase() !== origin &&
targetOrigin[1] !== cors_api_host) {
args[1] = cors_api_url + args[1];
}
return open.apply(this, args);
};
/****END DEALS WITH CORS****/
var xhr = new XMLHttpRequest();
xhr.open("GET", cors_api_url+url, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var resp = xhr.responseText;
var respWithoutDiv = removeErroneousData(resp);
}
else{
return "Failed to remove data.";
}
}
xhr.send();
}
remove div here:
/*This must be in JS not JQUERY, its in a web worker*/
function removeErroneousData(resp) {
var removedDivResp = "";
/*pseudo code for removing div*/
if (resp.contains(div with id disclosures){
removedDivResp = resp.removeData(div, 'disclosures');
}
return removedDivResp;
}
You can dump the response in a div and then search for that div you want empty its content.
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
var resp = xhr.responseText;
$('div').attr('id', 'resp').html(resp);
$('#resp').find('disclosures').html('');
//var respWithoutDiv = removeErroneousData(resp);
}
else{
return "Failed to remove data.";
}
}