You’ve finally realized the value of SOA (Service Oriented Architecturee) and decided to move all of your dynamic functionality into an independent service layer. Smart!
You start turning your cool dynamic features into REST JSON web services and then have your HTML sites (a.k.a consumer) query these services for JSON data (a.k.a. provider). However, the response from your web service is coming back blank, though the HTTP response status says 200 OK and you can see JSON data when accessing the web service endpoint directly. Sounds familiar?
What you may be dealing with here is known as a Cross-origin Resource Sharing (CORS) and covers situations where a web service you are querying is on a different site compared to the one initiating the request. Browsers ban such requests trying to comply with so-called “Same Origin Security Policy”.
Here, it is important to understand what a site is in this particular context:
So, even if your consumer is on “localhost:3000” and your provider is on “localhost:3001”, the response will be neglected unless your web service sets a permissive CORS policy. This policy is defined by the provider setting specific CORS headers in HTTP response that a consumer app (e.g. a browser) destined to enforce. For example, configuring these headers:
will allow a web service to service GET | POST | OPTIONS
requests from your
http://my-web-service-consumer-site.com
site.
If you want to allow multiple sites to access your web service, the recommended way is to have your
server read the Origin header from the consumer, compare that to the list of sites you’d like to allow,
and, if it matches, send the value of the Origin header back to the consumer as the
Access-Control-Allow-Origin
header in the response. Simply listing multiple sites or adding multiple
Access-Control-Allow-Origin
headers in the response doesn’t appear to produce consistent results
accross different browsers.
For those, who prefer to define CORS policy via Rack middleware, take a look at this rails-cors (https://github.com/cyu/rack-cors) gem.
Today my environment was:
- Rails 4.0.2
- rails-api 0.2.0