4

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!

4
  • Have you tried using jsonp? Commented Oct 19, 2013 at 17:25
  • @subzero — He doesn't run forecast.io, so he can't make them send a JSONP response. Commented Oct 19, 2013 at 17:27
  • @Quentin developer.forecast.io/docs/v2#options they do provide support for jsonp Commented Oct 19, 2013 at 17:38
  • Hmm, I assumed it wouldn't be supported since their official library doesn't use it … however the warning associated with that reference is not to be taken lightly. Commented Oct 19, 2013 at 17:40

3 Answers 3

2

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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

1 Comment

This is the superior answer - no server proxy needed.
0

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;
}

1 Comment

NOTE : a lot of people have 'RestangularProvider' rather than just 'Restangular' - but it amounts to the same thing.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.