user3379926
user3379926

Reputation: 3945

CORS issue with backbone

I have a site that is published and live which also has a api that I am trying to access from localhost:9000. This API is, or at least the parts I am trying to access do not require you to be authenticated in any way shape or form.

I set up a core collection in backbone:

AisisBlogger.Collections.AisisCollections = Backbone.Collection.extend({

  id: 0,

  page: 1,

  per: 10,

  route: '',

  tagName: '',

  categoryName: '',

  url: function() {
    var url;

    if (this.id !== 0) {
      url = 'http://writer.aisisplatform.com/api/v1/blogs/' + AisisBlogger.blogId + '/'+this.route+'/' + this.id
    } else if (this.tagName !== '' && this.route === 'posts') {
      url = 'http://writer.aisisplatform.com/api/v1/blogs/' + AisisBlogger.blogId + '/'+this.route+'?tag_name=' + this.tagName + '&page=' + this.page + '&per=' + this.per
    } else if (this.categoryName !== '' && this.route === 'posts') {
      url = 'http://writer.aisisplatform.com/api/v1/blogs/' + AisisBlogger.blogId + '/'+this.route+'?category_name=' + this.categoryName + '&page=' + this.page + '&per=' + this.per
    }else {
       url = 'http://writer.aisisplatform.com/api/v1/blogs/' + AisisBlogger.blogId + '/'+this.route+'?page=' + this.page + '&per=' + this.per
    }

    return url;
  },

  initialize: function(options){
    if (options !== undefined) {
      // Set id
      if (options.id !== undefined) {
        this.id = options.id;
      }

      // Set page
      if (options.page !== undefined) {
        this.page = options.page;
      }

      // Set per page
      if (options.per !== undefined) {
        this.per = options.per;
      }

      // Set the tag Id
      if (options.tagId !== undefined) {
        this.tagName = options.tagName;
      }

      // Set the category Id
      if (options.categoryId !== undefined) {
        this.categoryId  = options.categoryId
      }
    }
  }

});

From here I have the following collection:

AisisBlogger.Collections.Posts = AisisBlogger.Collections.AisisCollections.extend({

  route: 'posts'

});

Great, everything is lined up, so in a routes file I did the following call:

AisisBlogger.Routers.SiteBlog = AisisBlogger.Routers.AisisRouter.extend({

  page: 0,

  routes: {
    '': 'index',
    'post/:id': 'post',
    'posts/tags-archive/:tag': 'tags',
    'posts/categories-archive/:category': 'categories'
  },

  emptyView: function() {
    $('#blog').empty();
  },

  index: function() {
    this.emptyView();
    var postsCollection = new AisisBlogger.Collections.Posts();
    postsCollection.fetch().then(this.postsRecieved, this.serverError);
  },

  ...
}

So when I load the app and visit the index route I see nothing - I open the console and see:

XMLHttpRequest cannot load http://writer.aisisplatform.com/api/v1/blogs/2/posts?page=1&per=10. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:9000' is therefore not allowed access. 

If you follow the link, there are posts. there is a json object ready for me. But I cannot seem to access it. Now from what I understand this has to do with it being cross domain. So I have read or at least seen articles on "overriding backbone sync with cross origin ...." but they all want to do this for authentication reasons. This is just a GET api at this point, there is a POST, But you don't need to be authenticated for that either.

So whats the appropriate way to tackle this?

Upvotes: 0

Views: 98

Answers (1)

James C
James C

Reputation: 272

As the commenters have pointed out, the issue here is that the JSON file you are requesting is not 'allowing' you to access it from another domain. You need to configure the server to allow requests from your domain.

Consider an example. Say you're in the queue for a nightclub. Everybody wants to get in, but to make sure it doesn't get too crowded there's a guest list. Your name needs to be on the guest list in order to get in. In this example the club is the server, and the guest list is the CORS configuration. If your name (i.e. your app's domain) isn't on the guest list (the CORS configuration), you're not allowed in. No exceptions. To add your name to the guest list you need to set a header on the server in the syntax below:

Access-Control-Allow-Origin: (your domain here)

If you wanted to throw the doors open and let everyone in you can use the * wildcard:

Access-Control-Allow-Origin: *

To further extend an already strained analogy there might be different levels of access in the club (regular, VIP etc). On our server these types of access are the 'methods' we can use to make requests (GET, POST, et al). You set these with the following syntax:

Access-Control-Allow-Methods: (HTTP methods go here)

These are just two of the more common headers to set, there are many others. How you configure your club (i.e. server) depends on the server technology you use, there's more info on how to do this at the Enable CORS site.

Upvotes: 2

Related Questions