I created a html/javascript website running on an Apache Webserver on Mac OS X. This website consumes a .NET Webservice with JSON via XmlHttpRequest. This Webservice is running on a Windows Vista machine.
The website is accessible with this url: http://macintosh.companyname.local/~username/Sitename/index.html.
When I open the website on the Mac with Safari with this url I don't get any JSON data back from the Webservice.
When I open the website with the URL file://Users/username/Sites/Sitename/index.html it works perfectly.
My first thoughts are that is has something to do with XmlHttpRequest and it's security restrictions in many browsers, but I am not sure why it doesn't work when I call the site via the webserver instead of the absolute path to the html file.
Here the code I use to call the Webservice:
<div id="eigenRisico" class="panel" title="Eigen Risico">
<h2>Eigen Risico Per Polis</h2>
<script type="text/javascript">
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://webserviceurl/GetEigenRisicoVerzekerde", true);
xhr.onreadystatechange = function(){
if (xhr.readyState === 4) {
var result = eval('(' +xhr.responseText+')');
var ihtml="";
var j = 0;
for(i = 0; i < result.d.length/2; i++) {
ihtml=ihtml+"<fieldset><div class='row'><label>Polisnummer:</label><span>"+result.d[j]+"</span></div>";
j++;
ihtml=ihtml+"<div class='row'><label>Resterend Eigen Risico:</label><span>&euro "+result.d[j]+"</span></div></fieldset>";
j++;
}
document.getElementById('eigenRisico').innerHTML = ihtml;
}
};
xhr.setRequestHeader("content-type", "application/json");
var postData = '{"bsn": "999999999"}';
xhr.send(postData);
</script>
</div>
Does somebody knows why this is happening?
You can't do cross-domain ajax requests
See http://en.wikipedia.org/wiki/Same_origin_policy
You can get around this by setting up a proxy page on your own domain that will take the request and redirect it, then redirect the output back to you.
Are you running PHP? or other server-side processing?
Edit
Just to clarify your original problem, when reading from file://, the security policy is different that from http://. the local resource is considered trusted, and as such the ajax request is allowed to go through. As a web address, it just looks like one website is doing things in your name that maybe it shouldn't.
Related
I don't want solution using Node.js, FileReader, or whatever else exept javascript!
Developing the html page, I encountered a problem as follows:
I get accurate results with this procedure, unfortunately the procedure remembers result of the first login page. Whatever text file in the meantime change the content, the procedure returns the first result.
Can someone give advice!
var filePath = "../../dir/sub dir/text_file.txt";
function getBackData(filePath){
var axd, i, artx, txli, tdr;
if(window.XMLHttpRequest){
axd = new XMLHttpRequest();
}else{
axd = new ActiveXObject("Microsoft.XMLHTTP");
}
axd.open('GET', filePath, true);
axd.onreadystatechange = function(){
if(axd.readyState == 4 && axd.status == 200){
artx = axd.responseText;
txli = artx.split("\n");
for(i = 0; i < txli.length; i++){
alert(txli[i]);
}
}
}
axd.send(null);
}
You could try :axd setRequestHeader('Cache-Control', 'no-cache');
Or try: axd.open('GET', filePath+'?_=' + new Date().getTime()), true); This will prevent your server from using the cash, because each request is different.
This is probably because the browser cache it. If you send a parameter which is almost always different like timestamp, you can disable the cache. Or you can try to use POST, since post request are never cached.
You are not allowed to request local files directly with ajax - you need a server to serve them. The browser is sandboxed and cannot generally open local files. This is a security measure - imagine what would happen if any website was allowed to open your files!
There are ways to set up a simple server for your images, like http-server. This allows you to serve files directly off a chosen directory, like so:
npm install -g http-server
http-server path-to-text-files/
Then you can request the files normally with ajax, at a path relative to the one your server is serving, like so:
url = "/dir/subdir/text-file.txt";
...
ajax.open('GET', url, true);
...
ajax.send(null);
I'm currently working through the book "Head first HTML5 programming". I want to load the content of a file named sales.json from a web server on my own machine. I used wampserver for this.
In the folder wamp/www/gumball/ I put all relevant .html, .js and .css files, and also the sales.json file.
My JavaScript code is very simple:
window.onload = function() {
var url = "http://localhost/gumball/sales.json";
var request = new XMLHttpRequest();
request.open("GET", url);
request.onload = function() {
if (request.status == 200) {
updateSales(request.responseText);
}
};
request.send(null);
}
function updateSales(responseText) {
var salesDiv = document.getElementById("sales");
salesDiv.innerHTML = responseText;
}
This doesn't do anything! Typing the link: http://localhost/gumball/sales.json in my browser opens the right file, so the link should be correct. Even when using the .js files that come with the book (with a finished version of the application I'm trying to make), nothing loads.
Testing with alert statements tells me the request.onload event never happens. I'm clueless as to why this is the case.
A fact I don't quite understand yet: when I type: http://localhost/gumball/sales.json: in my browser (I added a colon at the end of the link), I get a 403 Forbidden error! Why does this happen? Does this have something to do with my problem?
I open html document with firefox
Your HTML document must be open with a URL in http://, not file://, if you want it to be able to open in javascript another document, unless the second document is served with relevant CORS headers.
This is due to same origin policy.
As you have a local WAMP server, there is no problem : simply open your file using a http:// URL like you do for your JSON file.
I am relatively new to JSON. I have read the tutorial and trying to implement it but no luck.
Basically I have an external URL that gives JSON data/feed. The data is in the form of array. Now I am trying to write a JavaScript Program (on my local) that would get the data out of this URL and would put in my html.
Here is the function. It includes the external link also.
But I am not getting any result. Just empty.
Am I missing something or what I am doing wrong?
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Index Page</title>
</head>
<body>
<div id="id01"></div>
<script>
var xmlhttp = new XMLHttpRequest();
var url = "http://mpatrizio-001-site5.smarterasp.net/categoryList.php?D=B7ACEF70-4901-41C8-930F-D4D681D82DAA";
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
var myArr = JSON.parse(xmlhttp.responseText);
myFunction(myArr);
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
function myFunction(arr) {
var out = "";
var i;
for(i = 0; i < arr.length; i++) {
out += arr[i].CategoryID + '<br>';
}
document.getElementById("id01").innerHTML = out;
}
</script>
</body>
</html>
UPDATE:
After being pointed in the right direction by you guys (thank you very much for that), I have found that the request is being blocked by server due to some CORS error. I am studying it.
Please review the following image of the error I got in the console.
From it, can you specifically point out the solution?
Append --disable-web-security (at path C;...\chrome.exe) in chrome's exe properties preceded by a space.
More Elegant Solution:
Other solution will be on server side. Which is to create crossdomain.xml and clientaccesspolicy.xml file on server. It's structure is like:
crossdomain.xml:
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="SOAPAction,Content-Type"/>
</cross-domain-policy>
clientaccesspolicy.xml:
<?xml version="1.0" encoding="utf-8"?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="SOAPAction">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource path="/" include-subpaths="true"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
Some of the tutorials are:
http://help.adobe.com/en_US/AS2LCR/Flash_10.0/help.html?content=00000469.html
http://www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html
Its specification is:
http://www.adobe.com/devnet-docs/acrobatetk/tools/AppSec/CrossDomain_PolicyFile_Specification.pdf
Other tutorials:
https://msdn.microsoft.com/en-us/library/cc197955(v=vs.95).aspx
What you are trying to do, Is a cross domain request. A cross domain request is also called a JSONP request amongst many more others and has two restrictions:
The first is that it restricts you only to "GET" requests, meaning you cannot issue a "POST" request to the cross domain server.
The second is that you are very limited by the server, meaning that if the server won't allow, you cannot get any data.
I would suggest you to read more about cross domain request before trying to go through this.
You are probably trying to execute an XMLHttpRequest to a domain that is different than your page is on, the browser will block this request. To allow the request you have to use CORS.
You can open the developer tools in Chrome (F12) and check for any error messages related to
"No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '[domainname]' is therefore not allowed access."
Thank to Muhammad Imran, Barr J and Luuk Moret, I am finally able to solve my problem.
It was the Cross domain request that's why it was not allowing me to get data.
So what I did,
I checked using test-cors.org the server to which I was sending request to see if CORS is configured or not. And the server was configured.
Then I installed this plugin for chrome, "Allow-Control-Allow-Origin: *" This plugin allows to you request any site with ajax from any source. Adds to response 'Allow-Control-Allow-Origin: *' header and Whola!. That solved my problem.
I hope this would help someone else.
I am trying to get text from a service on the same server as my webserver. The link is something like this:
http://<OwnIPadres>:8080/calc/something?var=that
This is my code:
function httpGet(theUrl)
{
alert(theUrl);
var doc = new XMLHttpRequest();
doc.onreadystatechange = function() {
if (doc.readyState == XMLHttpRequest.DONE) {
alert("text: " + doc.responseText );
document.getElementById('ctm').text = doc.responseText;
}
}
doc.open("get", theUrl);
doc.setRequestHeader("Content-Encoding", "UTF-8");
doc.send();
}
The url that i print in my first alert is the good one if i test in my browser, it is an html page with a table in it. But the alert of my text is empty? Is it a problem that the text is html?
Actually, its quite ok that your 'text' is 'html'. The problem is that using a different port counts as cross-site scripting. Therefore, your XMLHttpRequest is being stopped by the browser before it actually reaches your page across port 8080.
I'm not sure what else you're doing before and around this code snippet, but you could try an iframe call to your url to get your data, or you could add an
Access-Control-Allow-Origin: http://:8080/
in your header (however that will only get you the most modern browsers).
Finally, you could pull in a JS framework like JQuery which could help you with pulling in this service data.
<html>
<body>
<script type="text/javascript">
var req = new XMLHttpRequest();
req.open('GET', 'file://localhost/C:/Users/johan/mainMenu_2.html', false);
req.send(null);
if(req.status == 200)
dump(req.responseText);
var pageLinks = [];
var anchors = req.getElementsByTagName('a');
var numAnchors = anchors.length;
for(var i = 0; i < numAnchors; i++) {
//pageLinks.push(anchors[i].href);
document.write(anchors[i]);
}
</script>
</body>
</html>
With the access denied error on the 'GET' command
But I heard that you could get around this 'acces denied' error if you create an iframe and then read from that page. So how would you do this whitout using any server side languages?
file://localhost/C:/ is most definitely wrong.
Either use http://localhost or file://C:/
If possible, use a local web server because access to file:// URLs is riddled with restrictions in most browsers.
You can also, use relative path to the current page (without the domain name) to make a request. If this is going to be hosted in two different domains, then browsers would not allow you to do what you are doing, due to security restriction.
If you would like to perform from cross domain communication, you can follow Secure Cross-Domain Communication in the Browser.