Get JSON from PHP url within AngularJS factory - javascript

I have a AngularJS factory that has a method to get JSON from either a file on disk or from an URL.
The file approach is working okay. When I change it to use the remote URL, it isn't working. In Firefox it doesn't show me much information. I only get a warning about CORS or something? This is my code from the factory:
(function () {
var releasingFactory = function ($http) {
var factory = {};
factory.getCars = function(callback){
//return $http.get('/wagenplan/releasing.json');
return $http.get('http://www.athloncarlease.com/webservice/releasing.php').success(callback);
}
return factory;
};
releasingFactory.$inject = ['$http'];
angular.module('releasingApp').factory('releasingFactory', releasingFactory);
}());
I'm not sure if this will work.
The warning from FF Firebug is:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://www.athloncarlease.com/webservice/releasing.php. This can be fixed by moving the resource to the same domain or enabling CORS.
Any idea's?

I have read the article on Wikipedia about Same-origin policy. Perhaps you should skip "www." in the location string to be aligned with the rule: "same protocol, host and port".

Related

How to parse an RSS feed using JavaScript (External Domain)?

Question
I need to parse an RSS feed and display the parsed details in an HTML page.
Solution I Found
How to parse an RSS feed using JavaScript? is a very similar question and I followed it.
Using above question, I build the following code.
<script>
$(document).ready(function() {
//feed to parse
var feed = "https://feeds.feedburner.com/raymondcamdensblog?format=xml";
$.ajax(feed, {
accepts:{
xml:"application/rss+xml"
},
dataType:"xml",
success:function(data) {
//Credit: http://stackoverflow.com/questions/10943544/how-to-parse-an-rss-feed-using-javascript
$(data).find("item").each(function () { // or "item" or whatever suits your feed
var el = $(this);
document.write("------------------------");
document.write("title : " + el.find("title").text());
document.write("link : " + el.find("link").text());
document.write("description: " + el.find("description").text());
});
}
});
});
</script>
The Error
Failed to load
https://feeds.feedburner.com/raymondcamdensblog?format=xml: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost' is therefore not allowed access.
What I need
How can I change my code to read RSS feeds using JavaScript without getting above error?
You could use something like https://rss2json.com.
It parses the feed to json for javascript:
var feedURL = "https://feeds.feedburner.com/raymondcamdensblog?format=xml";
$.ajax({
type: 'GET',
url: "https://api.rss2json.com/v1/api.json?rss_url=" + feedURL,
dataType: 'jsonp',
success: function(result) {
console.log(result);
}
});
You're getting that error because of the same-origin policy. See below and/or read the full article at MDN:
For security reasons, browsers restrict cross-origin HTTP requests
initiated from within scripts. For example, XMLHttpRequest and the
Fetch API follow the same-origin policy. This means that a web
application using those APIs can only request HTTP resources from the
same origin the application was loaded from, unless the response
from the other origin includes the right CORS headers.
So your script is making a cross-origin HTTP request (which uses XMLHttpRequest through jQuery.ajax()) to https://feeds.feedburner.com/raymondcamdensblog?format=xml, but the CORS header of Access-Control-Allow-Origin is not being set by FeedBurner, therefore you get the "Failed to load ..." error. (But even if the header was set, if it didn't include your origin (localhost or some-domain.com), you'd still get the same error.)
So how can you change your code to read the RSS feeds using JavaScript without getting that error?
Use a third-party web service, just like what #Saeed suggested.
Create a server-side script (e.g. using PHP) that fetches the feed content and make AJAX requests to that script instead of directly requesting it from FeedBurner, or the actual source URL. See below for a simple example.
If I really had to, I'd probably ask FeedBurner to set the appropriate CORS headers...
Sample of a very simple PHP script for fetching the feed content:
<?php
// Set the feed URL.
$feed_url = 'https://feeds.feedburner.com/raymondcamdensblog?format=xml';
// Fetch the content.
// See http://php.net/manual/en/function.file-get-contents.php for more
// information about the file_get_contents() function.
$content = file_get_contents( $feed_url );
// Set the Content-Type header.
header( 'Content-Type: application/rss+xml' );
// Display the content and exit.
echo $content;
exit;
?>
So for example, you could save that to fetch-feed.php, and then in your JavaScript/jQuery script code, change the value of the feed variable like so:
var feed = "http://localhost/path/to/fetch-feed.php";
That way (i.e. using your own server-side script), you could at least be sure that the browser would always grant your XMLHttpRequest (or AJAX) request. (i.e. you wouldn't get the "No 'Access-Control-Allow-Origin' header" error)
You can also use jquery-rss or Vanilla RSS, which comes with nice templating and is super easy to use:
// Example for jquery.rss
$("#your-div").rss("https://feeds.feedburner.com/raymondcamdensblog?format=xml", {
limit: 3,
layoutTemplate: '<ul class="inline">{entries}</ul>',
entryTemplate: '<li>[{author}#{date}] {title}<br/>{shortBodyPlain}</li>'
})
// Example for Vanilla RSS
const RSS = require('vanilla-rss');
const rss = new RSS(
document.querySelector("#your-div"),
"https://feeds.feedburner.com/raymondcamdensblog?format=xml",
{
// options go here
}
);
rss.render().then(() => {
console.log('Everything is loaded and rendered');
});
See http://jsfiddle.net/sdepold/ozq2dn9e/1/ for a working example.
It's a CORS related error. You are getting that error because the URL from where you are requesting data does not have CORS enabled. CORS stands for 'Cross-Origin Resource Sharing'. If CORS is enabled on a server, your browser will let you make requests to that server. Otherwise, it will not.
https://feeds.feedburner.com/raymondcamdensblog?format=xml does not have CORS enabled, that's why your browser will not allow you to make ajax requests to that server. You can get around it by making the requests on your server and provide the data to the browser from your own server or a server that has CORS enabled.

Local development not possible with error: No 'Access-Control-Allow-Origin' header is present on the requested resource

I am pretty new in angularjs, and I am developing my first app. I prepared a backend Restful service in another system, which cannot be touched, and I developed my service. This the code:
var MainService = angular.module('MainService', [])
MainService.factory('MainData', ['$http', function ($http) {
var urlBase = 'http://demoint:1234/rest.oms/basvc/barest';
var MainData = {};
MainData.getData = function () {
return $http.get(urlBase + '/0/usecases?generation=true&UseCase=0.0.3550d.a6000015');
};
console.log(MainData);
return MainData;
}]);
But then I get this error on my browser:
XMLHttpRequest cannot load http://demoint:1234/rest.oms/basvc/barest/0/usecases?generation=true&UseCase=0.0.3550d.a6000015. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access.
I tried to bypass the problem in these ways but without luck:
adding this option to Chrome (startup parameter):
--disable-web-security
Adding this extension https://chrome.google.com/webstore/detail/allow-control-allow-origi/nlfbmbojpeacfghkpbjhddihlkkiljbi?hl=en
adding the config code below on my main app:
.config(['$httpProvider', function ($httpProvider) {
$httpProvider.defaults.useXDomain = true;
$httpProvider.defaults.withCredentials = true;
delete $httpProvider.defaults.headers.common["X-Requested-With"];
$httpProvider.defaults.headers.common["Accept"] = "application/json";
$httpProvider.defaults.headers.common["Content-Type"] = "application/json";
}
]);
Any idea about how to solve?
Thanks in advance!
Fabio
First of all JavaScript can't grant itself permission to access another website. means using only JavaScript you cant fix this issue.You have to enable CORS in back end server.
If you just want run this only on your browser you can disable web-security in chrome. For this close all the instance of chrome and run chrome.exe --disable-web-security.
For Chrome 49 plus check the link- Chrome 49 plus --disable-web-security

AngularJS and Basic HTTP Auth

I have an Angular app that is accessing a test database. This has worked before, but over the weekend I'm no longer allowed access. I have made no changes to the Angular code. Here's the issue.
For me to access the test database, I have to pass in the username and password since the database is using Basic HTTP Auth. My resource ends up looking like this.
angular.module("CoolApp.misc")
.factory('Ad', ad)
ad.$inject = ['$resource'];
function ad($resource) {
return $resource('http://username:password#build.com/api/advertisement.json');
}
Now when I run
Ad.get({}, function(resp) {}, function(badresp) {console.log(badresp)})
the console spits out the badresp object. I look inside my config headers section and notice this as the url...
url: "http://username#build.com/api/advertisement.json"
Wait a minute, I set the password in as the url. Why is the header not supplying me the password? Is that why I'm receiving a No 'Access-Control-Allow-Origin' header is present on the requested resource. in my console?
For kicks here is my http config
angular.module("CoolApp")
.config(config);
config.$inject = ["$httpProvider"];
function config($httpProvider) {
$httpProvider.defaults.useXDomain = true;
//$httpProvider.defaults.withCredentials = true;
delete $httpProvider.defaults.headers.common["X-Requested-With"];
$httpProvider.defaults.headers.common["Accept"] = "application/json";
$httpProvider.defaults.headers.common["Content-Type"] = "application/json";
}
My question is, what's wrong with this and how do I fix it?
No 'Access-Control-Allow-Origin' header is present on the requested resource. If you say you haven't changed the front-end code since the last time you touched it, then that can only mean that something on the server changed... Based on the error you've provided, it seems like a pretty clear case of somebody either removing the Access-Control-Allow-Origin on the server, or limiting the origins.
You can't change that on the client; that has to change on the server.

How to enable CORS in angular js

I am having a controller.js
ListNewsCtrl.$inject = ['$http', '$scope', 'datacontext'];
function ListNewsCtrl( $http, $scope, datacontext) {
$scope.names = [];
$http.get("http://www.w3schools.com/website/Customers_JSON.php")
.success(function (response) {$scope.names = response;console.log($scope.names)});
};
I get the data that I want. But when I change to a different site I get the followinf msg :
XMLHttpRequest cannot load https://URL. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3424' is therefore not allowed access. The response had HTTP status code 404.
The information I am trying to access are not requiring access token ?
The solution to my answer would be this :
http://blog.novanet.no/angularjs-with-jsonp-and-how-i-get-to-work-on-time/#2
However,I get this error : Uncaught SyntaxError: Unexpected token : I get small syntax issues . But at least I can see my data
CORS is enabled server-side. The domain you're requesting does not allow CORS requests, and that is not something you can edit or configure on the client end.
If the domain does allow CORS, then whatever you're using to host your local web server on localhost is not allowing it.
If cross-site requests are allowed, try
$http.jsonp("http://www.w3schools.com/website/Customers_JSON.php")
.success(function(data){
console.log(data);
});
I would not say its a perfect approach but better workaround for cors.
The Yahoo! Query Language is an expressive SQL-like language that lets you query, filter, and join data across Web services. Great thing about Yahoo YQL is that it is CORS-enabled :)
Client -> YQL -> API Server
Run Sample Here
$.getJSON("http://query.yahooapis.com/v1/public/yql",
{
q: "select * from json where url=\"https://erikberg.com/mlb/standings.json\"",
format: "json"
},
function (data) {
if (data.query.results) {
alert(data.query.results.json.standing);
} else {
alert('no such code: ' + code);
}
}
);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Here is a cool Tutorial
This will at least solve your cors problem in different ways.
Happy Helping!

Angular Cross-Origin Request CORS failure, but node http.get() returns successfully

I am trying to access an API using AngularJS. I have checked the API functionality with the following node code. This rules out that the fault lies with
var http = require("http");
url = 'http://www.asterank.com/api/kepler?query={"PER":{"$lt":1.02595675,"$gt":0.67125}}&limit=10';
var request = http.get(url, function (response) {
var buffer = ""
response.on("data", function (chunk) {
buffer += chunk;
});
response.on("end", function (err) {
console.log(buffer);
console.log("\n");
});
});
I run my angular app with node http-server, with the following arguments
"start": "http-server --cors -a localhost -p 8000 -c-1"
And my angular controller looks as follows
app.controller('Request', function($scope, $http){
// functional URL = http://www.w3schools.com/website/Customers_JSON.php
$scope.test = "functional";
$scope.get = function(){
$http.get('http://www.asterank.com/api/kepler?query={"PER":{"$lt":1.02595675,"$gt":0.67125}}&limit=10',{
params: {
headers: {
//'Access-Control-Allow-Origin': '*'
'Access-Control-Request-Headers' : 'access-control-allow-origin'
}
}
})
.success(function(result) {
console.log("Success", result);
$scope.result = result;
}).error(function() {
console.log("error");
});
// the above is sending a GET request rather than an OPTIONS request
};
});
The controller can parse the w3schools URL, but it consistently returns the CORS error when passed the asterank URL.
My app avails of other remedies suggested for CORS on this site (below).
Inspecting the GET requests through Firefox shows that the headers are not being added to the GET request. But beyond that I do not know how to remedy this. Help appreciated for someone learning their way through Angular.
I have tried using $http.jsonp(). The GET request executes successfully (over the network) but the angular method returns the .error() function.
var app = angular.module('sliderDemoApp', ['ngSlider', 'ngResource']);
.config(function($httpProvider) {
//Enable cross domain calls
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
});
You should understand one simple thing: even though those http modules look somewhat similar, they are totally different beasts in regards to CORS.
Actually, the node.js http.get() has nothing to do with CORS. It's your server that makes a request - in the same way as your browser does when you type this URL in its location bar and command to open it. The user agents are different, yes, but the process in general is the same: a client accesses a page lying on an external server.
Now note the difference with angular's $http.get(): a client opens a page that runs a script, and this script attempts to access a page lying on an external server. In other words, this request runs in the context of another page - lying within its own domain. And unless this domain is allowed by the external server to access it in the client code, it's just not possible - that's the point of CORS, after all.
There are different workarounds: JSONP - which basically means wrapping the response into a function call - is one possible way. But it has the same key point as, well, the other workarounds - it's the external server that should allow this form of communication. Otherwise your request for JSONP is just ignored: server sends back a regular JSON, which causes an error when trying to process it as a function call.
The bottom line: unless the external server's willing to cooperate on that matter, you won't be able to use its data in your client-side application - unless you pass this data via your server (which will act like a proxy).
Asterank now allows cross origin requests to their API. You don't need to worry about these workarounds posted above any more. A simple $http.get(http://www.asterank.com/api/kepler?query={"PER":{"$lt":1.02595675,"$gt":0.67125}}&limit=10')
will work now. No headers required.I emailed them about this issue last week and they responded and configured their server to allow all origin requests.
Exact email response from Asterank : "I just enabled CORS for Asterank (ie Access-Control-Allow-Origin *). Hope this helps!"
I was having a similar issue with CORS yesterday, I worked around it using a form, hopefully this helps.
.config(function($httpProvider){
delete $httpProvider.defaults.headers.common['X-Requested-With'];
$httpProvider.defaults.headers.common = {};
$httpProvider.defaults.headers.post = {};
$httpProvider.defaults.headers.put = {};
$httpProvider.defaults.headers.patch = {};
})
.controller('FormCtrl', function ($scope, $http) {
$scope.data = {
q: "test"//,
// z: "xxx"
};
$scope.submitForm = function () {
var filters = $scope.data;
var queryString ='';
for (i in filters){
queryString=queryString + i+"=" + filters[i] + "&";
}
$http.defaults.useXDomain = true;
var getData = {
method: 'GET',
url: 'https://YOUSEARCHDOMAIN/2013-01-01/search?' + queryString,
headers: {
'Content-Type': 'application/json; charset=utf-8'
}
};
console.log("posting data....");
$http(getData).success(function(data, status, headers, config) {
console.log(data);
}).error(function(data, status, headers, config) {
});
}
})
<div ng-controller="FormCtrl">
<form ng-submit="submitForm()">
First names: <input type="text" name="form.firstname">
Email Address: <input type="text" ng-model="form.emailaddress">
<button>bmyutton</button>
</form>
</div>
Seems to work with the url you posted above as well..
ObjectA: 0.017DEC: 50.2413KMAG: 10.961KOI: 72.01MSTAR: 1.03PER: 0.8374903RA: 19.04529ROW: 31RPLANET: 1.38RSTAR: 1T0: 64.57439TPLANET: 1903TSTAR: 5627UPER: 0.0000015UT0: 0.00026
I should also add that in chrome you need the CORS plugin. I didn't dig into the issue quite as indepth as I should for angular. I found a base html can get around these CORS restrictions, this is just a work around until I have more time to understand the issue.
After lots of looking around. The best local solution I found for this is the npm module CORS-anywhere. Used it to create AngularJS AWS Cloudsearch Demo.

Categories