koningdavid
koningdavid

Reputation: 8085

Access-Control-Allow-Origin and Angular.js

I've been trying to find a solution, but nothing I found so far worked. So I'm trying to do a HTTP request with angular to a weather API, but I keep getting this response:

Origin http://mydomain.com is not allowed by Access-Control-Allow-Origin. 

What I've tried so far:

  1. Adding this line to my app config

    delete $httpProvider.defaults.headers.common['X-Requested-With'];

  2. I Have tried multiple version's of angular, all with the same result

  3. Adding this to my .htacces

    Header add Access-Control-Allow-Origin "*"

  4. Adding the headers with PHP

  5. Trying different URL's for GET requests

    (even different API's, same result)

  6. Using the jQuery HTTP request instead of Angular's, same result...

My code

       $http({
          method: 'GET',
          url: 'https://api.forecast.io/forecast/myapikey/52.370216,4.895168'
        }).
        success(function(response) {
            console.log('succes');  
            console.log(response);
        }).
        error(function(response) {
            console.log('failed');  
            console.log(response);
        });

None of these solutions seem to work, I've been using Angular before and normally adding delete $httpProvider.defaults.headers.common['X-Requested-With']; would resolve the issue

I'm completely lost here, any help is appreciated, thanks!

Upvotes: 4

Views: 3080

Answers (3)

rushkeldon
rushkeldon

Reputation: 1391

Jorge had the right idea. $http.jasonp is the simplest route.

Here is an example using $q to return a deferred promise.

function getForecast( lat, lon ){
    var deferred = $q.defer();
    var apiKey = 'my-actual-api-key-here';
    var url = 'https://api.forecast.io/forecast/' + apiKey + '/' + lat + ',' + lon + '?callback=JSON_CALLBACK';

    $http.jsonp( url )
        .success( function forecastReceived( forecastData, status, headers, config ) {
            deferred.resolve( forecastData );
        } )
        .error( function forecastFailed( errorData, status, headers, config ) {
            deferred.reject( errorData );
        } );

    return deferred.promise;
}

or you can use (as I did) restangular, but you need to set it up first :

function isDataGood( forecastData ){
    var isGood = false;
    // test data here 
    // isGood = true;
    return isGood;
}

var apiKey = 'my-actual-api-key-here';
Restangular.setBaseUrl( 'https://api.forecast.io/' );
Restangular.setJsonp( true );
Restangular.setDefaultRequestParams( 'jsonp', { callback: 'JSON_CALLBACK' } );
var API = Restangular.one( 'forecast/' + apiKey );

function getForecast( lat, lon ){
   var deferred = $q.defer();

   function failed( error ){
       // TODO : retry logic here
       deferred.reject( error );
   }

   API
       .one( lat + ',' + lon )
       .get()
       .then(
           function forecastReceived( forecastData ) {
               if( isDataGood( forecastData ) ){
                   deferred.resolve( forecastData );
               } else {
                   failed( { msg : 'ERROR : received bad data' } );
               }
           },
           function forecastFailed( error ) {
               failed( error );
           } );

   return deferred.promise;
}

Upvotes: 0

Jorge Epuñan
Jorge Epuñan

Reputation: 760

You can use jsonp:

$http.jsonp('https://api.forecast.io/forecast/myapikey/52.370216,4.895168' +'?callback=JSON_CALLBACK')...

link: Make Jsonp Requests With AngularJs

Upvotes: 2

Quentin
Quentin

Reputation: 943097

api.forecast.io is not granting permission to mydomain.com.

Changing the headers being sent in the request won't help. Changing response headers sent by mydomain.com won't help.

The JavaScript library supplied by forecast.io uses a proxy. You'll need to take that approach too.

Upvotes: 2

Related Questions