How to reading out XMLHttpRequest responses - javascript

I'm doing a XMLHttpRequest like this:
var url = "myurl.html";
var http_request=new XMLHttpRequest();
http_request.onreadystatechange=function(){
if (http_request.readyState === 4){
console.log(http_request.response);
}
};
http_request.withCredentials = true;
http_request.open('GET',url,true);
http_request.send(null);
In the console http_request.response is empty but when I look in Chrome into the networks Tab I get this stuff
How do I get to this stuff from JavaScript?

The request comes from a different computer on the same network. The server at myurl.html doesn't allow "Access-Control-Allow-Origin". For this, in the header of the response must be something like this:
Access-Control-Allow-Origin: *
(* stands for wildcard)
When the header is lacking that information, Chrome will block the response in the JavaScript. Hence, the network tab will show the response but not the JS console. To bypass CORS in different browsers there are several methods. I used an extension from the Chrome web store for Chrome.
To further ensure that the request was done correctly, the callback function can be modified to this:
http_request.onreadystatechange = function () {
if(http_request.readyState === XMLHttpRequest.DONE && http_request.status === 200) {
console.log(http_request.responseText);
}
};
http_request.readyState should be 4, the status however should be 0 (even though in the Network tab it will appear as 200).

Related

Why Chrome sometimes makes 2 AJAX requests instead of 1?

I have encountered a strange behaviour of current version of Google Chrome (44.0.2403.157) on OS X.
When I do AJAX (XHR) request with method GET with my Chrome sometimes makes 1 request and sometimes - 2 (!).
My code:
var jsUrl = 'http://www.some-domain.com/xy.js';
var ajax = new XMLHttpRequest();
ajax.withCredentials = true;
ajax.open( 'GET', jsUrl, true ); // async, because sync cannot be send with cookies
ajax.onreadystatechange = function () {
var script = ajax.response || ajax.responseText;
if (ajax.readyState === 4) {
switch( ajax.status) {
case 200:
case 304:
eval.apply( window, [script] );
// no break on purpose here
default:
someFunction();
}
}
};
ajax.send(null);
A screenshot of my developer console when 2 requests are being made:
Server log confirms that the second request is being made - it's not just in the console.
The headers of the second request are practically the same as the first one - the only difference is the value of the cookie that is being changed with the 3rd request on the screen above.
Note that current version of Firefox (40.0.3) on OS X doesn't show this behaviour - only 1 request is made here, every time (tested by both watching request using Firebug (with BFCache requests shown) and by watching the server logs).
For a while I thought that using send() vs send(null) makes a difference - that when using send() only one request is being made - but after more tests I see that the strangeness is present with both syntaxes.
Can you give me a hint about what is happening here?

Not Receiving Asynchronous AJAX Requests When Sent Rapidly

My script is sending a GET request to a page (http://example.org/getlisting/) and the page, in turn, responds back with a JSON object. ({"success":true, "listingid":"123456"})
Here's an example snippet:
var listingAjax = new XMLHttpRequest();
listingAjax.addEventListener("load", listingCallback, false);
function listingCallback(event) {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
}
}
listingAjax.open("GET", "http://example.org/getlisting/", true);
listingAjax.send();
Simple enough. The script works perfectly too! The issue arises when I want to do this:
var listingAjax = new XMLHttpRequest();
listingAjax.addEventListener("load", listingCallback, false);
function listingCallback(event) {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
}
}
window.setInterval(function() {
listingAjax.open("GET", "http://example.org/getlisting/", true);
listingAjax.send();
}, 250);
What I imagine should happen is my script would create a steady flow of GET requests that get sent out to the server and then the server responds to each one. Then, my script will receive the server's responses and send them to the callback.
To be more exact, say I let this script run for 5 seconds and my script sent out 20 GET requests to the server in that time. I would expect that my callback (listingCallback) would be called 20 times as well.
The issue is, it isn't. It almost seems that, if I sent out two GET requests before I received a response from the server, then the response is ignored or discarded.
What am I doing wrong/misunderstanding from this?
Many browsers have a built in maximum number of open HTTP connections per server. You might be hitting that wall?
Here is an example from Mozilla but most browsers should have something like this built in: http://kb.mozillazine.org/Network.http.max-connections-per-server
An earlier question regarding Chrome:
Increasing Google Chrome's max-connections-per-server limit to more than 6
If you have Windows, take a look at a tool like Fiddler - you might be able to see if all of the requests are actually being issued or if the browser is queueing/killing some of them.
You can't reuse the same XMLHttpRequest object opening a new connection while one is in progress, otherwise it will cause an abrupt abortion (tested in Chrome). Using a new XMLHttpRequest object for each call will solve that:
function listingCallback(event) {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
}
}
window.setInterval(function() {
var listingAjax = new XMLHttpRequest();
listingAjax.addEventListener("load", listingCallback, false);
listingAjax.open("GET", "http://example.org/getlisting/", true);
listingAjax.send();
}, 250);
This will work nicely queueing a new ajax request for each interval.
Fiddle
Note that too frequent calls may cause slowdown due to the maximum limit of concurrent ajax calls which is inherent to each browser.
Though, modern browsers have a pretty fair limit and very good parallelism, so as long as you're fetching just a small JSON object modern browsers should be able to keep up even when using a dial-up.
Last time I made an ajax polling script, I'd start a new request in the success handler of the previous request instead of using an interval, in order to minimize ajax calls. Not sure if this logic is applicable to your app though.

XML accessible from URL line but not from script

When I type a certain URL in FF, I get the XML returned displayed on the screen, so the web service is apparently working. However, when I try to access it from a local HTML document running JS, I get unexpected behavior. The returned code is "200 OK" but there's no text (or rather it's an empty string) nor xml (it's null) in the response sections according to FireBug.
This is how I make the call.
var httpObject = new XMLHttpRequest();
httpObject.open("GET", targetUrl, true);
httpObject.onreadystatechange = function () {
if (httpObject.readyState == 4) {
var responseText = httpObject.responseText;
var responseXml = httpObject.responseXML;
}
}
httpObject.send(null);
Why does it happen and how do I tackle it?
That may be an HTTP header problem (e.g. missing Accept header); observe the headers sent by FF (you can use Firebug for that) and try to replicate them in your script (setRequestHeader).
Otherwise, that may be a "same origin policy" problem.

How to make a cross domain http get request using javascript?

I'm trying to implement sms functionality in Dynamics CRM 2011. I've created a custom activity for this and added a button to the form of an SMS. When hitting the button, a sms should be send.
I need to make an http request for this and pass a few parameters. Here's the code triggered:
function send() {
var mygetrequest = new ajaxRequest()
mygetrequest.onreadystatechange = function () {
if (mygetrequest.readyState == 4) {
if (mygetrequest.status == 200 || window.location.href.indexOf("http") == -1) {
//document.getElementById("result").innerHTML = mygetrequest.responseText
alert(mygetrequest.responseText);
}
else {
alert("An error has occured making the request")
}
}
}
var nichandle = "MT-1234";
var hash = "md5";
var passphrase = "[encryptedpassphrase]";
var number = "32497123456";
var content = "testing sms service";
mygetrequest.open("GET", "http://api.smsaction.be/push/?nichandle=" + nichandle + "&hash=" + hash + "&passphrase=" + passphrase + "&number=" + number + "&content=" + content, true)
mygetrequest.send(null)
}
function ajaxRequest() {
var activexmodes = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"] //activeX versions to check for in IE
if (window.ActiveXObject) { //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
for (var i = 0; i < activexmodes.length; i++) {
try {
return new ActiveXObject(activexmodes[i])
}
catch (e) {
//suppress error
}
}
}
else if (window.XMLHttpRequest) // if Mozilla, Safari etc
return new XMLHttpRequest()
else
return false
}
I get the "access is denied error" on line:
mygetrequest.open("GET", "http://api.smsaction.be/push/?nichandle=" ......
Any help is appreciated.
The retrieving site has to approve cross domain AJAX requests. Usually, this is not the case.
You should contact smsaction.be or check their FAQ to see if they have any implementation in place.
Usually JSONP is used for cross domain requests, and this has to be implemented on both ends.
A good way to overcome this, is using your own site as a proxy. Do the AJAX requests to an script on your side, and let it do the call. In example PHP you can use cURL
I suppose the SMS-service is in different domain. If so, you cannot make AJAX-call to it, because it violates same origin policy. Basically you have two choices:
Do the SMS-sending on server-side
Use JSONP
Also, is it really so that the passphrase and other secrets are visible in HTML? What prevents people from stealing it and using it for their own purposes?
Your AJAX requests by default will fail because of Same Origin Policy.
http://en.wikipedia.org/wiki/Same_origin_policy
Modern techniques allow CORS ( see artilce by Nicholas ) http://www.nczonline.net/blog/2010/05/25/cross-domain-ajax-with-cross-origin-resource-sharing/
jQuery's Ajax allow CORS.
Another way to do it is to get the contents and dynamically generate a script element and do an insertBefore on head.firstchild ( refer jQuery 1.6.4 source line no : 7833 )
Google analytics code does some thing similar as well. you might want to take a look at that too.
Cheers..
Sree
For your example, when requesting from different domain error is:
XMLHttpRequest cannot load http://api.smsaction.be/push/?nichandle=??????&hash=?????&passphrase=[???????????]&number=????????????&content=???????????????. Origin http://server is not allowed by Access-Control-Allow-Origin.
For cross domains XMLHttp requests destination server must send Access-Control-Allow-Origin response header.
MDN: https://developer.mozilla.org/en/http_access_control

XMLHttpRequest.status always returning 0

html
click me
js code
var MyObj =
{
startup : function()
{
var ajax = null;
ajax = new XMLHttpRequest();
ajax.open('GET', 'http://www.nasa.gov', true);
ajax.onreadystatechange = function(evt)
{
if(ajax.readyState == 4)
{
if (ajax.status == 200)
{
window.dump(":)\n");
}
else
{
window.dump(":(\n");
}
}
}
ajax.send(null);
}
}
ajax.status always returning 0, no matter which site it is, no matter what is the actual return code. I say actual, because ajax.statusText returning correct value, eg OK or Redirecting...
ajax.readyState also returns proper values and 4 at the end.
You can overcome this easily in a local environment by setting up a php proxy (xampp a server and pass a querystring for the url you want to grab). Have your php proxy wget the url and echo its contents. That way your local html file (when viewed as http://localhost/your.html) can send ajax requests out of domain all day. Just don't expect the content to work as though it were local to that domain.
Is your site part of http://www.nasa.gov/? Otherwise, XMLHttpRequest will fail due to Same Origin Policy.
Also, if the page is served as a non-HTTP request, the status can be 0. See https://developer.mozilla.org/En/Using_XMLHttpRequest#section_3.

Categories

Resources