Say I'm interested in checking the params that were sent with the XMLHttpRequest.
For instance, if I sent a POST petition with param 'option=1' can I retrieve that from the response?
I checked for the methods and properties but haven't seen a way to get it.
Fire a XMLHTTPRequest and examine the response object in your browser's JS console (F12 for Chrome/Firefox).
I believe the data is not there, at least I once changed the XMLHttpRequest open() method for a project (of course, I might have been just too stupid to find it). That way, my default error handler knows the original URL when printing errors to the user/sending errors to the error reporting backend.
Rough code snippet, pulled from a projects init-code:
/**
* Check XMLHttpRequest availability
*/
var ajax = null;
var proto = null;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest ();
proto = XMLHttpRequest.prototype;
} else if (window.ActiveXObject) {
try {
ajax = new ActiveXObject("Msxml2.XMLHTTP.6.0");
proto = ActiveXObject("Msxml2.XMLHTTP.6.0").prototype;
} catch (e) { }
}
if (ajax == null) {
alert ("Can not create AJAX object. You need a more recent browser!");
return;
}
/**
* Update ajax prototype to store the URL (for better error handling)
*/
try {
var origOpen = proto.open;
proto.open = function (method, url) {
this._url = url;
return origOpen.apply (this, arguments);
}
} catch (e) {
console.log ("Can not patch XMLHttpRequest to store URL. Console output will omit them...");
}
You would need to adapt this for POST data passed to the send() function instead. Be aware, that the method is probably bad style, and my JS style might be even worse!
Better: But you could always pass the POST data directly to the callback function, without storing it in the XMLHTTPRequest object:
var postData = "SomeStuff-Foobar123";
var ajax = new XMLHttpRequest (); //add magic for other browsers here
ajax.open ("POST", "ajax.php", true);
ajax.onreadystatechange = function () {
if (this.readyState != 4 || this.status != 200) {
console.log ("Not ready, yet...");
return 0;
}
//response is in this.responseText
//but you can still access the parent objects!
console.log ("Done with Code 200. POSTed data: " + postData);
}
ajax.send (postData);
As Bergi said it's not possible to retrieve the parameters that were sent with the request on the response. So I'm closing the question.
Thanks to everyone who helped!
Related
Just to point out, I know how to do this with jQuery and AngularJS. The project I am currently working on requires me to use plain JavaScript.
I'm trying to get AJAX to work with just plain JavaScript. I am using Java/Spring for backend programming. Here is my JavaScript code:
/** AJAX Function */
ajaxFunction = function(url) {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.status == 200) {
var JSONResponse = JSON.parse(xhttp.responseText);
return JSONResponse;
}
}
xhttp.open('GET', url, true);
xhttp.send();
}
/** Call Function */
searchResults = function() {
var test = ajaxFunction('http://123.456.78.90:8080/my/working/url');
console.log(test);
}
/** When the page loads. */
window.onload = function() {
searchResults();
}
It's worth noting that when I go directly to the URL in my browser's address bar (example, if I go directly to the link http://123.456.78.90:8080/my/working/url), I get a JSON response in the browser.
When I hover over xhttp.status, the status is saying 0, not 200, even though I know that the link I am calling works. Is this something that you have to set in Spring's controllers? I didn't think that was the case because when I inspect this JS URL call in the Network tab, it states that the status is 200.
All in all, this response is coming back as undefined. I can't figure out why. What am I doing wrong?
An XMLHttpRequest is made asynchronously meaning that the request is fired off and the rest of the code continues to run. A callback is provided and when the asynchronous operation completes the callback function is called. The onreadystatechange function is called upon completion of an AJAX request. In your example the ajaxFunction will return immediately after the xhttp.send() line executes, so your var test won't have the JSON in it as I assume you expect.
In order to do something when an AJAX request completes you need to use a callback function. If you wanted to log the result to the console as above you could try something like the following:
var xhttp;
var handler = function() {
if(xhttp.readyState === XMLHttpRequest.DONE) {
if (xhttp.status == 200) {
var JSONResponse = JSON.parse(xhttp.responseText);
console.log(JSONResponse);
}
}
};
/** AJAX Function */
var ajaxFunction = function(url) {
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = handler;
xhttp.open('GET', url, true);
xhttp.send();
};
/** Call Function */
var searchResults = function() {
ajaxFunction('http://123.456.78.90:8080/my/working/url');
};
/** When the page loads. */
window.onload = function() {
searchResults();
};
If you want to learn more about how XMLHttpRequest works then MDN is a much better teacher than I am :)
When I was trying a simple code to test XMLHttpRequest() function, I used this code:
<script>
//Global variable to store the XMLHttpRequest object
var myRequest;
//Package the request into its own function
function getData()
{
//Feature-testing technique to make sure the browser
//supports the XMLHttpRequest object
if (window.XMLHttpRequest)
{
//create a new instance of the object
myRequest = new XMLHttpRequest();
}
//else - the XMLHttpRequest object is not supported:
//create an instance of ActiveXObject
else
{
myRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
//Use the open(retrievalMethod, "myDataFile.txt", bool) method
myRequest.open("GET", "test.txt", true);
//Use send() with a null argument - we have nothing to send:
myRequest.send(null);
//attach a function to handle onreadystatechange,
//that is, the response from the server:
myRequest.onreadystatechange = getData;
alert(myRequest.responseText);
}
</script>
I want to simply return the contents of my 'test.txt' file.
Now,
When I am running this code, I get nothing! I see only a blank screen.....
And now,
When i set Asnyc parameter to false, It Works!
Why??
XMLHttpRequests that point to local files isn't possible out of the box (xmlhttprequest for local files).
Your getData()-method should contain something like this:
funtion getData (requestObject) {
if (request.readyState === 4) {
//DO STUFF
}
}
The reason why it works when you execute the request sync is because you probably didn't include the above code.
Hey guys I am using a executePostHttpRequest function that looks exactly like the code posted below. Currently when I run the function I get a server response with the appropriate data but I am not sure how I can work with the response data? how do I store it in to a variable to work with?
Javascript executePostHttpRequest
function executePostHttpRequest(url, toSend, async) {
console.log("====== POST request content ======");
console.log(toSend);
var xmlhttp = new XMLHttpRequest(); // new HttpRequest instance
xmlhttp.open("POST", url, async);
xmlhttp.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xmlhttp.setRequestHeader("Content-length", toSend.length);
xmlhttp.send(toSend);
console.log("====== Sent POST request ======");
}
Here is what I am doing to execute it. Using Javascript
var searchCriteria = JSON.stringify({
displayName : search_term
});
console.log("Search: "+searchCriteria) //Search: {"name":"John, Doe"}
var response = executePostHttpRequest("/web/search", searchCriteria, true);
console.log(response) //undefined
So currently the console.log for response shows undefined. But if I take a look at the network tab on Chrome Dev Tools and look at the /web/search call I see a JSON string that came back that looks something like this.
[{"id":"1","email":"john.doe#dm.com","name":"John, Doe"}]
I'd like to be able to display the data from this response to a HTML page by doing something like this.
$("#id").html(response.id);
$("#name").html(response.name);
$("#email").html(response.email);
I tried taking another route and using Jquery POST instead by doing something like this.
var searchCriteria = JSON.stringify({
displayName : search_term
});
console.log("Search: "+searchCriteria) //Search: {"name":"John, Doe"}
$.post("/web/search", {
sendValue : searchCriteria
}, function(data) {
$.each(data, function(i, d) {
console.log(d.name);
});
}, 'json').error(function() {
alert("There was an error searching users! Please contact administrator.");
});
But for some reason when this runs I get the "There was an error" with no response from the server.
Could someone assist me with this? Thank you for taking your time to read it.
Your executePostHttpRequest function doesn't do anything with the data it's receiving. You would have to add an event listener to the XMLHttpRequest to get it:
function getPostData(url, toSend, async, method) {
// Create new request
var xhr = new XMLHttpRequest()
// Set parameters
xhr.open('POST', url, async)
// Add event listener
xhr.onreadystatechange = function () {
// Check if finished
if (xhr.readyState == 4 && xhr.status == 200) {
// Do something with data
method(xhr.responseText);
}
}
}
I've added the method parameter for you to add a function as parameter.
Here's an example of what you were trying to do:
function displayStuff(jsonString) {
// Parse JSON string
var data = JSON.parse(jsonString)
// Loop over data
for (var i = 0; i < data.length; i++) {
// Get element
var element = data[i]
// Do something with its attributes
console.log(element.id)
console.log(element.name)
}
}
getPostData('/web/search', searchCriteria, true, displayStuff)
I'm trying something very simple for my first Firefox Add-On, the important part is:
Step 1) Call an external API to retrieve some data.
Step 2) Call that API again with the data retrieved the first time to get some more.
Now, I first implemented it using XMLHttpRequest in synchronous mode, since I thought the need to wait for Step 2 forced me to do it that way. Two calls to the function that dealt with the API call, used XMLHttpRequest and parsed the response. Fine.
Then I came accross various docs in the Mozilla Development Network which encourage you to use XMLHttpRequest in asynchronous mode and so I tried.
Basing my implementation on multiple XMLHttpRequests and others I came up with the code below.
My question is: Is this the proper way to do it? Should I go back to using synchronous mode? It works like this, but it just doesn't strike me as the correct AJAX pattern you would use...
// first call
var username = foo;
var password = bar;
var startOffset = 0; // initial value
var url = encodeURIComponent('https://theapiurl.com/query=' + startOffset);
doRequest();
function doRequest() {
makeRequest(url, username, password);
}
function makeRequest(url, username, password) {
var http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}
if (!http_request) {
alert('Cannot create XMLHTTP instance');
return false;
}
http_request.onreadystatechange = function() {
alertContents(http_request);
};
http_request.open('GET', url, true, username, password);
http_request.send(null);
}
function alertContents(http_request) {
if (http_request.readyState == 4) {
if (http_request.status == 200) {
if (startOffset == 0) {
startOffset = 45; // this value would be extracted from 'http_request'
url = encodeURIComponent('https://theapiurl.com/query=' + startOffset);
// second call, parameter startOffset has changed
doRequest();
} else {
}
} else {
alert('There was a problem with the request.');
}
http_request.onreadystatechange = function fnNull(){};
}
}
You should always avoid doing synchronous network requests as it will block the GUI from functioning until you get a response. Just because the network may be fast for you, you should not assume it will be fast for all of your users.
I am trying to get the html of a website using this code:
function catchData(req) {
console.debug("i got a reply!");
var returnXML = req.responseXML;
console.debug(returnXML);
if (!returnXML)
{
console.debug("html is bad");
return;
}
if (speed != currentSpeed)
moveToNewSpeed(speed);
currentSpeed = speed;
var error = returnXML.getElementsByTagName('message')[0].firstChild;
if (error) {
document.getElementById('errorMessage').innerHTML = error.nodeValue;
document.getElementById('errorMessage').style.visibility = 'visible';
}
else
document.getElementById('errorMessage').style.visibility = 'hidden';
}
function sendRequest(url,callback,postData) {
console.debug(url);
console.debug(postData);
var req = createXMLHTTPObject();
if (!req) return;
var method = (postData) ? "POST" : "GET";
console.debug(method);
req.open(method,url,true);
console.debug("request Opened");
req.setRequestHeader('User-Agent','XMLHTTP/1.0');
req.setRequestHeader('User-Agent','XMLHTTP/1.0');
if (postData)
{
req.setRequestHeader('Content-type','application/x-www-form-urlencoded');
console.debug("set post data");
}
req.onreadystatechange = function () {
if (req.readyState != 4)
{
console.debug("bad ready state");
return;
}
console.debug(req);
console.debug("responseText:");
console.debug(req.responseText);
callback(req);
console.debug("callback finished");
}
if (req.readyState == 4) return;
req.send(postData);
}
var XMLHttpFactories = [
function () {return new XMLHttpRequest()},
function () {return new ActiveXObject("Msxml2.XMLHTTP")},
function () {return new ActiveXObject("Msxml3.XMLHTTP")},
function () {return new ActiveXObject("Microsoft.XMLHTTP")}
];
function createXMLHTTPObject() {
var xmlhttp = false;
for (var i=0;i<XMLHttpFactories.length;i++) {
try {
xmlhttp = XMLHttpFactories[i]();
}
catch (e) {
continue;
}
break;
}
return xmlhttp;
}
When I do a wireshark grab I see the server returning the html, but req.responseText is just an empty string. Anyone know whats up?
I guess you're trying to get the HTML of a page that's on a different domain than your JavaScript. This is a cross-domain request, which isn't allowed in Javascript. This is usually seen as empty responses in your script.
The JSONP standard describes a mechanism to retrieve JSON from a different domain, but this needs to be implemented on the other site and doesn't work with HTML.
The Yahoo! Query Language (YQL) can act as a proxy. The Yahoo! server will fetch the HTML and create a JSONP response, which your script will receive. This may help you to accomplish your goal. The YQL has a lot of cool features for retrieving content from other sites, I recommend you read through the documentation to see if there's anything else you can use.
from where is the javascript being executed? Do you have a same-origin policy violation?
I ask because I have seen wierdness in these situations, where I was violating the policy but the request was still going out; just the response was empty...it doesn't make any sense that the browser would send the request, but they all handle it differently it appears...
Is there a reason why you're writing this code yourself instead of using a library such as jQuery? You'll find it much easier and they've already figured out all the associated quirks with browser interoperability, etc.