XMLHttpRequest.status always returning 0 - javascript

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.

Related

javascript opening a new window, setting its content AND its location without reloading that location for security

I am trying to implement an HTTP(due to memory resource limitation on embedded devices I can't use HTTPS) webserver security system.
I need to do this in case a hacker deploy a webserver with the same IP as mine (yes I know about IP conflict it shouldn't be possible but I tried and it worked) or hack my DNS server which will result in his server and mine to have the same domain for the browser and as result, the hacker can access the session storage in which I'm storing credentials (i know I shouldn't use session storage for credentials but due to many other vulnerabilities this is the best I can work with).
For this reason, before opening every page I must check that the received page is actually the original webpage and not a page sent by a hacker (phishing page for example) to extract the credentials, if it is a valid page I can continue and open it in the browser, and if not valid an alert is shown.
I check the validity of the page by checking a turning key only known by a (locally saved HTML file or a browser's extension) and the server with an ajax function. The key is sent with the page in the header:
var url="http://192.168.8.14";
......
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200)
{
if (xhr.getResponseHeader("identity_key") == identity_key)
{
//ORIGINAL WEB PAGE
}
}
};
xhr.open("GET", url+"?userIndex="+userIndex+"&identificationSalt="+identificationSalt, true);
xhr.send(null);
now i have all the validated html page inside the xhr.responseText which i would like to open inside a new tab or current tab and with the location pointing to url because the validated page contain relative paths and javascript src files with relatives paths which need the location to work like this :
<script src="sha.js"></script> or window.location.href = "http://"+window.location.host+"/controle
but when the location is pointing to the URL it mustn't reload the page otherwise the browser will load another page that is not validated.
I tried every way I can think of including this :
var url="http://192.168.8.14";
......
xhr.onreadystatechange = function()
{
if(xhr.readyState == 4 && xhr.status == 200)
{
if (xhr.getResponseHeader("identity_key") == identity_key)
{
history.pushState(null, null, url);
document.documentElement.innerHTML=xhr.responseText;
}
}
};
xhr.open("GET", url+"?userIndex="+userIndex+"&identificationSalt="+identificationSalt, true);
xhr.send(null);
but it gave me this error:
Uncaught DOMException: Failed to execute 'pushState' on 'History': A history state object with URL 'http://192.168.8.14/' cannot be created in a document with origin 'null' and URL 'file:///C:/Users/ladne/Desktop/Untitled-1.html'.
at XMLHttpRequest.xhr.onreadystatechange (file:///C:/Users/ladne/Desktop/Untitled-1.html:73:33)
error
i also tried :
var page = window.open();
page.document.open();
page.document.location="http://192.168.8.14/";
page.document.write(xhr.responseText);
page.document.close();
can anyone help, please?

Adblocker blocks XMLHttpRequest

I understand the fact, that adblockers try to deny loading (image) data later on. Anyway, I want to send some data to a php script (/log.php) to save it in a sql database. So in fact I don't care about the responsetext. This is my current js function I use to call the php script:
function log(id, unix_ms, frameid, eventtype, targetid, value){
var parameters = "";
parameters = parameters.concat("id=", encodeURI(id), "&unix_ms=", encodeURI(unix_ms), "&frameid=", encodeURI(frameid), "&eventtype=", eventtype, "&targetid=", targetid, "&value=", value);
var httprequest = new XMLHttpRequest();
httprequest.open("POST", "/scripts/log.php", true);
httprequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
httprequest.onreadystatechange = function() {
if(httprequest.readyState == 4 && http.status == 200) {
console.log(httprequest.responseText);
}
}
httprequest.send(parameters);
}
What can I change to pass the adblocker? I mean facebook uses things like ajax in masses to load text and even images in the timeline.
Is there maybe a way to use frames in the background since I don't care about the answer?
After analysing the log as suggested in a comment I found out that log.php seems to be in the blocklist, even if it's on the same server. So name you php files a little more complex to avoid this.
log.php -> submitlog.php

How to reading out XMLHttpRequest responses

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).

Is it possible to get page redirect information via Ajax?

Without ajax, if we load http://example.com/1 and if it redirects to http://example.com/2 then the browser gets appropriate headers and the Browser URL get's updated. Is there a way to get this information via jQuery Ajax?
For example, I am requesting http://api.example.com via Ajax. In PHP, this page is redirected to http://api2.example.com. Is it possible to know this thing?
Use:
I have a navbar which has links. All pages are loaded into the container via AJAX and I push the url on Browser Bar using HTML5 history as per the link.
However, if the page gets redirected, the page would have a new link right? I would like to change that in the Browser bar too. I would like to know where the Ajax URL is redirected in case it is redirected.
Why this is important?
My links handle form data, requests and various authentications. For example, if I request, https://oauth.example.org?code=56hycf86 it either redirects to success or failure page. My Ajax get the right html content but the URL browser bar still has the URL with same Auth ID which, if reloaded, produces error. There are other security issues too.
I do not know if I explained things right, but thanks for your help.
Well, unfortunately, ajax always follows redirects. However, there is a feature that is not supported in all browsers, you can access the responseURL property of the XMLHttpRequest object.
You can try it in the below code snippet. the redirect button sends ajax request to a URL that replies with 1 redirect (it also works if there are multiple redirects).
The no redirect button sends ajax request to a URL with no redirects.
As far as I know this method is not supported in IE 11 and older versions of chrome/firefox/opera browsers.
document.getElementById("no-redirect").addEventListener("click", function() {
testRedirect("https://httpbin.org/get");
});
document.getElementById("redirect").addEventListener("click", function() {
testRedirect("https://httpbin.org/redirect/1");
});
function testRedirect(url) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(e) {
if (xhr.status == 200 && xhr.readyState == 4) {
if (url != xhr.responseURL) {
alert("redirect detected to: " + xhr.responseURL)
} else {
alert("no redirect detected")
}
}
}
xhr.open("GET", url, true);
xhr.send();
}
<button id="redirect">
Redirect
</button>
<button id="no-redirect">
No Redirect
</button>
This might not be exactly what you're looking for, but maybe it will help you get a similar effect.
If you are in control of what the page http://api.example.com does, you could change the way it reacts when it gets a call via AJAX.
You could include a variable in your AJAX call, marking it as such a call, and if this variable is present, not redirect to an other page, but include the URL it would redirect to, in the answer.
The data returned in the AJAx call could be a hash, in which one key represents the redirect url.
data = {status => 1, redirect => 'http://ap2.example.com', …}
(Sorry if that is not a valid PHP hash)
not sure if I understood it, but just tried something, if it is not what you're looking for please notify me to delete the answer.
here we inject this /#/ in the URL so when clicking on links the browser will have a new segment in the URL which represent the parameter that depending on its value you can determine which page to load using the corresponding AJAX call..
JS/jQuery:
var navLinks = $('#nav a'),
params = [],
baseURL = '//localhost/test/js-url-parameters-second';
navLinks.each(function(){
var oldHREF = $(this).attr('href');
$(this).attr('href', baseURL +'/#/'+ oldHREF);
});
navLinks.on('click', function(){
checkURL($(this).attr('href'));
});
function checkURL(docURL){
// if /#/ found then we have URL parameters
// grabbing the parameters part of the URL
if(docURL.indexOf('/#/') > -1){
docURL = docURL.split('/#/')[1];
if(docURL != ''){
// omit the last forward slash if exists
if(docURL[docURL.length - 1] == '/'){
docURL = docURL.substring(0, docURL.length - 1);
}
console.log(docURL);
$('#page-type').text(docURL);
}
} else {
console.log('No URL parameters found');
}
}
HTML:
<div id="nav">
Home
About
Contact
</div>
<hr>
<div id="container">
this is the <span id="page-type">Home</span> page
</div>
As the already mentioned responseURL doesn't have the best browser support yet, there are 2 more alternative for this case that could be used, http request headers and cookies.
The benefit with these is they don't interfere with the content itself, like for example query string keys, hash tags or embedded in the response data.
Request headers
Server side
PHP
$req->addHeader("X-Response-Url", "....");
ASP
headers.Add("X-Response-Url", "....");
Client side
xhr.onreadystatechange = function(e) {
if (xhr.status == 200 && xhr.readyState == 4) {
var resp_url = xhr.getResponseHeader("X-Response-Url");
if (send_url != resp_url) {
// redirected
}
}
}
Cookies
PHP
setcookie("XResponseUrl", "...");
ASP
Response.Cookies("XResponseUrl") = "..."
Client side
xhr.onreadystatechange = function(e) {
if (xhr.status == 200 && xhr.readyState == 4) {
var resp_url = getCookie("XResponseUrl");
if (send_url != resp_url) {
// redirected
}
}
}
function getCookie(name) {
var re = new RegExp(name + "=([^;]+)");
var value = re.exec(document.cookie);
return (value != null) ? unescape(value[1]) : null;
}
Yes, when you request http://api.example.com using Ajax, browser does not redirect. You can get all the response using jQuery like bellow
$.ajax({
url: "http://api.example.com",
success: function(data, textStatus, xhr) {
console.log(xhr.status);
},
complete: function(xhr, textStatus) {
console.log(xhr.status);
}
});

json response across multiple domains

well i am doing a website which should read markers from a db and then populate them on the map. If i work locally it works fine but when i point to a php file is online thus different domain ( which requests data from the db ) i am not getting any response and i am having JSON.parse: unexpected end of data. Note i dont want to change anything in the php file because another website is already using this file. the function which is calling and doing the request is shown below... your help is much appreciated.
function ajaxrequestDB() {
var AJAX = null; // Initialize the AJAX variable.
if (window.XMLHttpRequest) { // Does this browser have an XMLHttpRequest object?
AJAX=new XMLHttpRequest(); // Yes -- initialize it.
}
else { // No, try to initialize it IE style
AJAX=new ActiveXObject("Microsoft.XMLHTTP"); // Wheee, ActiveX, how do we format c: again?
} // End setup Ajax.
if (AJAX==null){ // If we couldn't initialize Ajax...
alert("Your browser doesn't support AJAX."); // Sorry msg.
return false // Return false, couldn't set up ajax
}
AJAX.onreadystatechange = function() { // When the browser has the request info..
if (AJAX.readyState==4 || AJAX.readyState=="complete")
{ // see if the complete flag is set.
//alert(AJAX.responseText);
var result =JSON.parse(AJAX.responseText);
//alert(AJAX.responseText);
for (var i=0; i<result.length; i++) {
for (var j=0; j<gmarkers.length; j++) {
if (gmarkers[j].myname == result[i].name) {
gmarkers[j].setVisible(true);
gcircle[j].bindTo('center', gmarkers[j], 'position');
gcircle[j].setVisible(true);
var cat = gmarkers[j].mycategory;
}
}
}
callback(AJAX.responseText, AJAX.status); // Pass the response to our processing function
} // End Ajax readystate check.
}
//var url='http://localhost/refresh.php'; //this works !
var url='http://anotherdomain.org/Scripts/refresh.php';
AJAX.open("GET", url, true); // Open the url this object was set-up with.
AJAX.send(); // Send the request.
}
function callback(x, y) {
// alert(x);
}
You have to use cross-domain techniqes such as JSONP. Browsers does not allow accessing servers in a different domain.
Ajax queries traditionally need to be sent to the same server because of the same origin policy.
You can allow connection from other site by adding
<?php header("Access-Control-Allow-Origin: *"); ?>
to you PHP script.
An alternative would be to use JSONP

Categories

Resources