Jun 14, 2013

Meteor. Request to host is not allowed by Access-Control-Allow-Origin.

As a novice I'd like to describe a situation when you may need to make calls to a different domain. In my case it was a requirement to access external API. Anyway I'd like to describe here my perspective of usage this in meteor. You would need to get those data and parse them. First thought is to use client. Wrong. You would need to add CORS support to your application.
It means you need to have header Access-Control-Allow-Origin: * added to all of your response objects. This will enable Meteor usage of external domain responses. And requires you to hack Meteor code.

But there is more "proper" way to work with server. Code on a server is executed synchronously and so you can be sure it will be executed and result returned.
So. First we need to make sure we have a Meteor.http package installed. You can install it by executing "meteor add http" in your project root directory.
Meteor.http can work in both synchronous and asynchronous modes. It is differed by defining a callback function to a http.call() method. In our example we will make a http request on external server and work with it on a client.
Here is your client and server code:
url = 'http://.........'

if (Meteor.is_client) {

    // Calling our Meteor server's function 
    // and simply storing data into current session
    Meteor.call('fetchDataFromUrl', function (error, response) {
        Session.set('external_server_data', response)
    });


    // Providing meteor data for template (it renders on data received)
    Template.data.server_data = function () {
        return Session.get('external_server_data');
    };

}

if (Meteor.is_server) {

    Meteor.methods({
        // Declaring a method
        retrieve_doc_types: function () {
            this.unblock();
            return Meteor.http.get(api_url);
        }
    });
    
}
And the template to display their result:
<head>
    <title>data from your server</title>
</head>

<body>
 <h1>Data from your server:</h1>
 {{> data}}
</body>

<template name="data">
 {{server_data}}
</template>
It was quite enough to me to make calls to external API. You can also add something like JSON.parse somewhere in server side to make your data posted in a proper manner. But it is out of the scope of this article. Also please note this.unblock(); method.

Please comment/suggest!

No comments:

Post a Comment