I'm trying to get data from a external api, but
I keep getting the error message:
XMLHttpRequest cannot load... No 'Access-Control-Allow-Origin' header is present on the requested resource.
here is my code:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script type="text/javascript">
(function () {
$.support.cors = true;
$.ajax({
type: "GET", url: "http://zhettoapi.azurewebsites.net/api/Values?product=Coca Cola", success: function (data) {
window.alert("" + data);
//example of setting innerHTML of object
document.getElementById("myElement").innerHTML = "The number is:" + data;
}, error: function (xhr, status, error) {
// Display a generic error for now.
alert("Error: " + xhr + " " + status + " " + error);
}
});
})();
</script>
</head>
<body>
<div id="myElement"></div>
</body>
</html>
Since i can see that use have used azurewebsites mentioned in Get url ( "http://zhettoapi.**azurewebsites**.net/api/Values.... ), and i have some experience on that, i thought of solving your problem, even if this question was not tagged with Azure.
Assumption : You have used WebAPI.And deployed on Azure as website. ( i am sure, it is).
Since you are trying to access Azure Web API url from other domain in form of ajax.get request, it gets blocked because of cross domain ( CORS) security. So first thing here, is to make it(hosted WebAPI project) CORS enabled.
Steps to make it CORS enabled:
Install this - Install-Package Microsoft.AspNet.WebApi.Cors using NuGet
Open the file App_Start/WebApiConfig.cs. Add the following code to the WebApiConfig.Register method.
Next, add the [EnableCors] attribute to the Controller class:
With following params
[EnableCors(origins: "http://zhettoapi.azurewebsites.net", headers: "", methods: "")]
Redeploy your WebAPI project.
SOURCE - http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api
More links - http://www.codeproject.com/Articles/742532/Using-Web-API-Individual-User-Account-plus-CORS-En
Thanks!
Also this tutorial was helpful(describing):
http://www.codeguru.com/csharp/.net/net_asp/using-cross-origin-resource-sharing-cors-in-asp.net-web-api.html
Related
I am working on an ajax function that loads another page as a way to get around iframe limitations on Shopify. My issue seems to be that the URL is blocked or headers stripped. Nothing too complex, everything worked as I needed it to by using the following:
function get_report() {
var params = {
type: "GET",
url: "https://example.com/mypage.php",
dataType: 'html',
success:function(html) {
$("#content_div").load("https://example.com/mypage.php");
},
error: function(XMLHttpRequest, textStatus) {
alert('Error : ' +XMLHttpRequest.response);
}
};
jQuery.ajax(params);
};
<button onclick="get_report()">Get</button>
<div id="content_div"></div>
This works through public networks with no problem. However, when my client uses it behind a company firewall it fails to load the page. Upon further inspection it appears that the site URL my php is hosted on cannot be loaded either (I cannot be there to physically confirm). Here is a sample of that page if its relevant:
<?php
$allowedOrigins = [
"https://myexample.com",
"https://myexample2.com"
];
if (array_key_exists('HTTP_ORIGIN', $_SERVER)) {
$origin = $_SERVER['HTTP_ORIGIN'];
} else if (array_key_exists('HTTP_REFERER', $_SERVER)) {
$origin = $_SERVER['HTTP_REFERER'];
} else {
$origin = $_SERVER['REMOTE_ADDR'];
}
if (in_array($origin, $allowedOrigins)) {
header("Access-Control-Allow-Origin: " .$origin);
}
setcookie('cross-site-cookie', 'name', ['samesite' => 'None', 'secure' => true]);
?>
<!DOCTYPE HTML>
<html lang="en">
<head>
<meta charset="utf-8">
<title>TEST ALT IFRAME</title>
</head>
<body>
<div><?php echo "IT WORKS"; ?></div>
</body>
</html>
What I know:
-Walked client through accessing chrome console, zero errors listed
-URL never loads when client tries to load it via browser
-Ajax never gives an error response
-Webmaster/IT team is unreachable (I have tried to contact them for at least 4 months)
What I've tried:
-Recently adding meta tags and !DOCTYPE (just in case)
-Validating both the iframe site and URL site with W3C
-Confirming both the iframe site and URL site work with VPN and public networks
-Checking for correct categorization on major network filtering groups (semantics, paleo-alto, etc) and set to 'SAFE'.
My Question:
-How do I find out if the URL is blocked or the ajax request is being stripped?
-If the network is filtering my ajax URL am I at a dead end or is there another option?
How do I find out if the URL is blocked or the ajax request is being stripped?
If there's a network error, you can respond to it in the error callback you pass to the AJAX call:
function get_report() {
var params = {
type: "GET",
url: "https://example.com/mypage.php",
dataType: 'html',
success:function(html) {
$("#content_div").load("https://example.com/mypage.php");
},
error: function(XMLHttpRequest, textStatus) {
// inspect XMLHttpRequest to determine if network error occurred
alert('Error : ' +XMLHttpRequest.response);
}
};
jQuery.ajax(params);
};
If the network is filtering my ajax URL am I at a dead end or is there another option?
You're sort of at a dead end at the application level, unless you're willing to do something really convoluted like have a third party service, that you know will not have firewall restrictions, request the page, and then forward it to a service that is accessible from behind that firewall. So the short answer is, no, not really (at least not practically)
I want to create a JS file that others can include on their websites so they can reference the functions which access my db using an api similar to the facebook like button which shows the total liked and who of your friends like the page. What I've been doing as part of my testing is the following:
JS file
function getItemRating(id){
var result = "";
$.ajax({
type: "POST",
url: "http://siteurl.com/api/rating.php",
data: {i : id},
dataType: "json",
async: false,
success: function(data) { // callback for successful completion
result = data;
},
error: function() { // callback if there's an error
result = 'error';
}
});
return result;
}
Reference file includes:
header("Access-Control-Allow-Origin: *");
and on the other server I've tried a few ways including:
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<script src="//code.jquery.com/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="www.siteurl.com/api/rating-file.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var result = getItemRating(1);
console.log(result);
});
</script>
</head>
<body></body>
</html>
But currently I'm getting the error in console:
VM133:1 Access to XMLHttpRequest at 'http://siteurl.com/api/rating.php' from origin 'http://otherurl.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
siteurl.com = my server where the js file (with function) is located
otherurl.com = different server that the html including the js is located
The error message tells you that the problem is with the response to the preflight request, but you shouldn't be triggering one in the first place.
Remove:
contentType: "application/json; charset=utf-8",
because:
It is a lie. You aren't POSTing JSON in your GET request.
Setting the content-type to that value triggers a preflight request.
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.
I'm working on a simple PhoneGap application that communicates with a server that runs PHP, gets a string and displays it in JavaScript alert.
The App works perfectly fine on a browser. The JavaScript alert displays the string returned by the PHP code on the server. This action happens on click event of a button.
Here is the markup:
<!DOCTYPE html>
<html xml:lang="en" lang="en">
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no;">
<title>PhoneGap</title>
<script type="text/javascript" charset="utf-8" src="jquery.min.js"></script>
<script src="cordova.js" charset="utf-8" type="text/javascript"></script>
<script type="text/javascript" charset="utf-8" src="index.js"></script>
</head>
<body>
<h1>Hello World!</h1>
<button id="eventfire">Click</button>
</body>
</html>
JS code
$(document).ready(function(){
$("#eventfire").click(function(){
var data = {
"action": "test"
};
data=$.parseJSON('{ "name": "John" }');
$.ajax({
type: "POST",
dataType: "text",
url: "http://192.168.x.x/HelloWorldTest/response.php", //Relative or absolute path to response.php file
data: data,
success: function(data) {
alert(data);
alert("type is " + typeof data + ". Length is " + data.length);
},
error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.statusText);
alert(xhr.responseText);
alert(xhr.status);
alert(thrownError);
},
statusCode: {
400: function () {
alert("Bad request!");
},
401: function() {
alert("Unauthorized!");
},
403: function() {
alert("Forbidden!");
},
404: function() {
alert("Page not found!");
},
408: function() {
alert("Request Timeout!");
},
200: function() {
alert("page reached");
},
}
});
});
})
PHP code
<?php
echo 'john';
?>
When I run this code on a AVD, the alert does not display the string. I have never seen such a alert getting displayed. The alert displayed inside the success function is shown below.
On inspecting this string, I understood that the length is 0.
I was able to reproduce the same issue on browser with a string of 0 characters length.
I'm not sure why the piece of code that is working fine when run on browser but acts weirdly on AVD. The string was getting displayed as expected on browser but not on AVD.
Find below the screenshots of the same code displaying the correct alert on browser.
I want to know the possible reasons of why the string from PHP is getting lost ?
I've never used PhoneGap but since your php file is stored on a different server than the files trying to call it, you will need to enable Cross-Origin Resource Sharing (CORS) (though I can't be sure this is the only issue)
Try adding Header set Access-Control-Allow-Origin "*" in your server's .htaccess file
By default, servers block access to resources like php files when the request comes from a file that is not stored on the same server.
For example, if I have a js file located at http://myfirstwebsite.com/awesome.js and in that file I make an ajax call to http://mysecondwebsite.com/loadstuff.php, the request will be blocked by the server and will produce the following error in the console:
XMLHttpRequest cannot load http://mysecondwebsite.com/loadstuff.php. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://mysecondwebsite.com' is therefore not allowed access.
I'm not sure if you can see this error in PhoneGap or where as I have never used it.
As the warning alludes to, in order to fix this, you must set the 'Access-Control-Allow-Origin' header to allow remote files to access the ones on your server.
Here is a tutorial explaining how to do that on Ubuntu
Just in case that link ever dies, here are the steps (copied right from that site)
Make sure you have the mod_headers Apache module installed. to do this check out /etc/apache2/mods-enabled/ and see if there’s a ‘headers.load’ in there. If there isn’t then just sudo ln -s /etc/apache2/mods-available/headers.load /etc/apache2/mods-enabled/headers.load
Add the Access-Control-Allow-Origin header to all HTTP responses. You can do this by adding the line Header set Access-Control-Allow-Origin "" to the desired section in your configuration file (like the /etc/apache2/sites-available/default file). Saying "" will allow cross-site XHR requests from anywhere. You can say "www.myothersite.com" to only accept requests from that origin.
Reload apache server. sudo /etc/init.d/apache2 reload
I would like to use javascript to consume the web weather service provided by cdyne.
This is my code:
<html>
<head>
<title>weather app</title>
</head>
<body>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script language="JavaScript">
function CallService() {
var DTO = "{ 'ZIP': '85281' }";
$.ajax({
type: "POST",
url: "wsf.cdyne.com/WeatherWS/Weather.asmx/GetCityWeatherByZIP",
data: JSON.stringify(DTO),
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: true,
success: function (msg) {
alert(msg);
},
error: function (req, status, error) {
alert(req + "# " + status + "# " + error);
},
complete: function (req, status) {
alert(req + "% " + status);
}
});
}
CallService();
</script>
</body>
</html>
When I ran the code, it shows the [object Object]#error# and [object Object]%error in the alert, which means the error: function() and complete: function rather than success: function() are called. Is there anyone who used javascript to consume this weather service?
Any help will be greatly appreciated.
There are a few problems there:
Your URL should start with http://. Without it, the URL you have is resolved relative to the document the code is in.
You're sending JSON in the POST. The odds are very high that the service doesn't expect to receive a POST containing JSON.
You're expecting JSON back from the service, but it appears to reply with XML.
You're trying to do a cross-origin call, but that's prevented by the Same Origin Policy, and the service you're trying to use doesn't appear to support Cross Origin Resource Sharing. (When I tried it fixing the issues above, I got the error saying that the cross-domain request wasn't allowed from my origin [which was http:/jsbin.com]).
Looking at the service description for the page you're trying to use, it doesn't look like it supports JSON-P, either, which means you can't use it from a different domain. You'll have to use a server-side process to query it.
You cannot do ajax requests to a different domain, fiddle http://jsfiddle.net/wAt45/
XMLHttpRequest cannot load
http://wsf.cdyne.com/WeatherWS/Weather.asmx/GetCityWeatherByZIP. Origin
http://fiddle.jshell.net is not allowed by Access-Control-Allow-Origin.