Cross Domain XML to Javascript from PHP - javascript

I want to send XML data from php(domain A) to a remote javascript file(domain B).
I can't have them on the same domain, and I can't have any other files on on domain B.
I've read about sending a JSONP object from php instead of XML, but as I understood from a tutorial, I would need a php proxy on the same domain as where the javascript file is located. tutorial link
(xhr.open("GET", "xmlproxy.php?url=" + escape(url), true); <= this line kinda tells me, that the xmlproxy.php has to be on the same domain as the actuala javascript)
Any suggestions, on how could I do this?
LATER EDIT AFTER ThW's answer
Now I have the following sample code :
The testlog.php file
<?php header('Access-Control-Allow-Origin: *');
print "<Logs><Log><id>Test Log</id></Log></Logs>";
?>
The javascript function that is called on page load:
function getTestLog() {
alert("Gets here!");
$.ajax({
url: "anotherdomain/testlog.php",
data: requestVars,
dataType: 'xml',
success: function(xml){
alert(xml);
},
error: function (xhr, err) {
alert("Error: " + xhr.readyState + "\nstatus: " + xhr.status + "\nerror:" + err);
alert("responseText: " + xhr.responseText);
}
});
}
The problem is, that it's not getting into the ajax thing

If you control the PHP that outputs the XML you can use CORS.
By default Javascript can only open resources from the domain it was loaded. Other resources have to allow that they can be loaded by a Javascript on a different domain.
To do that add a header to the PHP-Script:
header('Access-Control-Allow-Origin: http://javascript-domain.tld');
Or to allow the loading of the XML from anywhere:
header('Access-Control-Allow-Origin: *');
You're using jQuery and here might be a problem if you're not sending the correct content type from PHP.
header('Content-Type: application/xml');
To validate that it is the Cross Domain that it is blocking the reading open you Javascript console in the browser. It should output an error message. In Firefox it is something like:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://domain.tld/path/to/resource. This can be fixed by
moving the resource to the same domain or enabling CORS
If you get the request, it should show up in the Network-Tab of your developer tools and you can validate the HTTP response headers.
Here is simple JS snippet using XHR, it forces the content type.:
var xhr = new XMLHttpRequest;
xhr.overrideMimeType("application/xml");
xhr.addEventListener(
'load',
function (xhr) {
return function () {
if (xhr.status >= 200 && xhr.status < 400) {
console.log(xhr.responseXML);
}
}
}(xhr)
);
xhr.open('GET', 'http://php-domain.tld/script.php');
xhr.setRequestHeader("Accept", "application/xml");
xhr.send();

Related

Running Javascript function from another domain [duplicate]

This question already has answers here:
How does the 'Access-Control-Allow-Origin' header work?
(19 answers)
Closed 4 years ago.
To start off JS is NOT my strong suite. What I am trying to do is run some code between 2 sites. So for example we have site A, and site B.
Site B contains a file called auth.js which the content is below.
function test() {
alert("bingo");
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
// document.getElementById("demo").innerHTML = this.responseText;
alert( this.responseText );
}
};
xhttp.open("POST", "https://siteb.com/auth.php", true);
xhttp.send();
};
Now inside site A I am including auth.js and running the function test()
As of now I am getting the alert message fine, however I'm receiving a console message about CORS (which i googled a bit and it doesn't make sense to me).
All of the code is living on site B. I'm wanting to run a php script when this js file is called, then output the data back as javascript on site A. So my php script will do all of the authentication and structure new js code and echo it out.
What am I missing to make CORS work properly?
Thanks in advance.
ok so finally got some code to work for me. Heres what I did.
inside auth.php on Site B I've added the following lines of code.
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
Right now this is allowing all traffic to come through. If you want to restrict it to a specific domain, then swith the * to http://example.com
and also modified the file auth.js on Site B
function test() {
alert("bingo");
$.ajax({
type: 'POST',
url: 'https://siteb.com/auth.php',
crossDomain: true,
data: {},
async: false,
success: function(response) {
alert(response);
},
error: function (jqXHR, textStatus, errorThrown) {
alert(errorThrown);
alert(textStatus);
}
});
};
so now on site A. I'm calling only test();
hope this helps someone else
Make a PHP file which will send the request in PHP CURL, gets the response and sends that response to the browser. Instead of sending a request from Javascript to the final target, send this to your own server and make sure your PHP is being executed. This should resolve the CORS issue. Other potential problems will be that you will have to make sure that the script, link, a, img tags have proper path.

Access-control-allow-origin issue on server side?

I need to send a get request to a company internal website on client side. Here is my code:
<head>
<script src="https://code.jquery.com/jquery-1.12.4.js" integrity="sha256-Qw82+bXyGq6MydymqBxNPYTaUXXq7c8v3CwiYwLLNXU=" crossorigin="anonymous"></script>
<script type='text/javascript'>
$(document).ready(function () {
var url = 'https://jsonplaceholder.typicode.com/photos'; //working
//var url = 'xxxxxxx'; //internal url (returns json), not working
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true)
xhr.onload = function () {
if (xhr.readyState === xhr.DONE) {
console.log(xhr.response)
console.log(xhr.responseText)
}
}
xhr.send()
})
</script>
</head>
This works fine with a test url that I put in (of course, having different domain than my server), meaning that it works fine with CORS request.
However, it doesn't work with the internal company url. The error I got is “No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'abc'(my server) is therefore not allowed access.”
My question: What caused the error? Why my CORS request works with one website but not the other? Is there some restrictions on my company's internal website, e.g. my server is not whitelisted on its "origin firewall"?
Interesting enough, it works (i.e. I'm able to get the json response) if I use ajax and set dataType to jsonp. But of course, because the returned data is json not jsonp, I got a different error saying "unexpected token :". This made me to doubt myself. If it was something placed by the internal website, why does ajax/jsonp trick work?
The ajax code below works - it got valid json response. However, because the returned data is json not jsonp, I got a different error (as I expeted).
$.ajax({
url: 'xxxxxxx', //internal url (returns json)
dataType: 'jsonp',
success: function( response ) {
console.log( response ); // server response
}
});

XMLHttpRequest - REST from javascript

I am having a webserver running on my localhost. If i load my webpage from my webserver everything works fine. I am able to OPEN a REST session with my webserver.
JS code :--
$(document).ready(function() {
var xhr = new XMLHttpRequest();
var open_str = "http://localhost:8080/vscp/rest?user=admin&password=d50c3180375c27927c22e42a379c3f67&format=json&op=1";
xhr.open("GET", open_str, true);
xhr.onreadystatechange = function() {
alert(xhr.readyState + "" + xhr.status);
if (xhr.readyState == 4 && xhr.status == 200) {
alert("session opend success");
var json = JSON.parse(xhr.responseText);
alert(JSON.stringify(json, null, 10));
}
}
xhr.send();
});
HTML code :--
<!DOCTYPE html>
<html>
<head>
<title>Hello jQuery</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<script src="hello.js"></script>
</head>
<body>
<div>
<p class="greeting-id">Trying to open the REST session with vscpd </p>
</div>
</body>
</html>
Now if i load the same html page from my D: drive :--
file:///D:my_folder/htm_test.html
I am getting following error "No 'Access-Control-Allow-Origin' header is present". And i have checked in javascript code that xhr.readyState is 4 and xhr.status is 0.
Please suggest what changes to make to my javascript code so that, if i open the html file directly from my D: drive using file:/// then also REST session is opened correctly with my webserver.
========================= JSONP code ========================
$(document).ready(function() {
var url = "http://localhost:8080/vscp/rest?user=admin&password=d50c3180375c27927c22e42a379c3f67&format=json&op=1";
function jsonpCallback(response) {
alert('success');
}
$.ajax({
url: url,
dataType: 'jsonp',
error: function(xhr, status, error) {
alert("error" + " " + error.message);
},
success: jsonpCallback
});
return false;
});
Error i get :--
server is sending the right response :--
{"success":true,"code":1,"message":"success","description":"Success","session-id":"e5a36e14b687c37b615dbc6a9506df5c","nEvents":0}
But ajax call giving error for this response i.e "Uncaught SyntaxError: Unexpected token :"
You have run into the Same Origin Policy - this is a security mechanism that restricts JavaScript loaded from one domain from sending requests to a different domain.
There are various ways around it, if you are using Google Chrome I would suggest setting the --allow-file-access-from-files flag when you start the browser, Firefox also provides a way to work around it, but don't forget to disable these options when you have finished testing, they are there for a good reason!
That's because Chrome and some other browsers are blocking the local files for security reasons and I don't think there is a method for resolving this issue. You have to use a webserver.

How to make http authentication in REST API call from javascript

I need to call OpenMRS REST API from Java script to get data from OpenMRS. Below is my java script code:
function myfunction(){
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://localhost:8081/openmrs-standalone/ws/rest/v1/person?q=John", false);
xhr.setRequestHeader("Authorization: Basic YWRtaW46QWRtaW4xMjM");
xhr.send("");
alert(xhr.status);
}
Where YWRtaW46QWRtaW4xMjM is my base64 coded username:password as explained here. If I do not put the authorization line in the code and check the web app using Firebug, it returns 401 unauthorized status that is expected. But if I put the authorization, nothing is returned and in firebug I do not see any response as well. If I check the URL directly on browser, the page asks for username and password and after giving correct credential, it returns the data normaly. So I am getting some problem of providing the http authentication right from the java script of the app. I have also considered the methods explained here but no luck. Can anyone please help me to authorize the http request right from the javascript?
Here is another similar but different example of how to set the header for authorization purposes, but instead using JQuery and AJAX.
var token = "xyz"
var url = "http://localhost:8081/openmrs-standalone/ws/rest/v1/person?q=John"
$.ajax({
url: url,
beforeSend: function(xhr) {
xhr.setRequestHeader("Authorization", "Bearer " + token)
},
})
.done(function (data) {
$.each(data, function (key, value) {
// Do Something
})
})
.fail(function (jqXHR, textStatus) {
alert("Error: " + textStatus);
})
Below is also an example of how you might get an access token using xhr instead of AJAX.
var data = "grant_type=password&username=myusername#website.com&password=MyPassword";
var xhr = new XMLHttpRequest();
xhr.withCredentials = true;
xhr.addEventListener("readystatechange", function () {
if (this.readyState === 4) {
console.log(this.responseText);
}
});
xhr.open("POST", "https://somewebsite.net/token");
xhr.setRequestHeader("cache-control", "no-cache");
xhr.setRequestHeader("client_id", "4444-4444-44de-4444");
xhr.send(data);
Beware of cross-site domain requests(if you're requesting a token that's not on localhost or within the domain that you are currently working in), as you'll need CORS for that. If you do run into a cross-domain issue, see this tutorial for help, and be sure you have enabled CORS requests from the API as well.

Ajax Authorization Request headers fails again and again

I'm working on a consumer for a self-made API and having serious difficulties with setting the Authorization header. I am using JQuery for the Ajax requests, but the 'beforeSend' does not work at all (using fiddler to examine the requests)
This is my beforeSend code:
$.ajax({
type: "GET",
url: url+"/Projects",
contentType: "application/json; charset=utf-8",
beforeSend: function (req) {
req.setRequestHeader("Authorization", AuthBuilder(username, password));
},
success: function (result) {
alert("success");
},
error: function (xhr, ajaxOptions, thrownError) {
alert("fail");
}
});
Well if that fails what do you do? Go back to the old way for sending ajax requests... well this doesn't work either...
This is my regular code:
function GET(address, callback, error) {
Request = getXMLHttpObject();
Request.open("GET", url + address, true);
var base64 = Base64.encode(username + ":" + password);
alert(base64);
Request.setRequestHeader("Authorization", "Basic " + base64);
Request.send();
Request.onreadystatechange = function () {
//alert(Request.readyState+" code "+Request.status);
if (Request.readyState == 4 && Request.status == 200) {
callback(jQuery.parseJSON(Request.responseText));
} else if (Request.readyState == 4 && Request.status >= 400) {
error(Request.status, Request.statusText);
}
}
}
Don't mind the fact that I'm not asking for json specifically because the service returns json by default.
In additional info:
the origin does not matter, the service allows all origins (has been tested and confirmed)
the Authorization works when set by headers (tested in other clients)
the Authorization headers just aren't sent
AuthBuilder(username, password)) gives the correct format of the Basic Auth header content
the getXMLHttpObject() is just some copy paste code and worked before
any thoughts ?
Well I found out what the problem was. The self-made service sent this back to the client as a global header : "Access-Control-Allow-Headers" with only "Content-Type" in it.
This way our clients not using an User Agent (browser) ignored these headers and just sent the header anyway. But the browser tried to optimize the request and said "It won't accept the Authorization header so I'll just cut it before sending." this way is the package is smaller and the service won't allow it anyway (although it did...)
So just adding "Authorization" to the Access Control Allow Headers part of the service made my Javascript/JQuery/Ajax requests send the request header as normal!

Categories

Resources