Same-Origin policy and working around it

Scripting languages like Javascript are restricted on their ability to call a service hosted on a domain different than their own domain by a policy implemented in the browsers called the same-origin policy.

The domain is determined by 3 parameters of the url:

– protocol

– host

– port number

If any of this differs between the caller domain and the callee domain, the javascript call to the callee domain will return an error saying cross domain requests are not allowed.

More information: http://en.wikipedia.org/wiki/Same_origin_policy

To overcome this constraint, at least 3 solutions exist today:

JSONP – JSON with Padding

This is an older technique supported by all the browsers. This works if you are calling a service which returns a JSON response. You make the service call as the ‘src’ attribute value of a <script> tag and pass the name of the callback function in the url. The service will then respond back with a javascript call to the callback function and the JSON response will be passed as the parameter to that function. You implement the callback function in your javascript code and this is where you will receive your response.

The deal with JSONP is that it is not secure since any javascript can be injected in this way by the server. Also, this approach works only for HTTP GET requests.

CORS – Cross Origin Resource Sharing

This was introduced to provide a more secure solution than JSONP and now CORS is supported by all latest browsers. CORS involves addition of some new HTTP headers in the response from the server. The browser on receiving these headers will determine if the javascript call is allowed or not. Primary amongst these headers is

Access-Control-Allow-Origin: *

A value like ‘*’ will allow requests from any domain to call this service. A more restricted value can be applied to limit successful requests from specific domains only.

Apart from this, there are a number of other headers that may/may not be needed for CORS to work depending on your call. Some of them are as below:

Access-Control-Allow-Methods: <comma separated list of methods that the server allows>

Access-Control-Allow-Headers: <comma separated list of headers allowed by the server in the client request>

Apart from this, the server should also support a call to HTTP OPTIONS method which the client calls during a preflight request. The preflight request is made prior to making the actual HTTP request to the desired method and is used to determine the allowed HTTP methods that the server supports and also the allowed origins. When the OPTIONS request returns a successful response, the browser automatically will make the actual HTTP call for the desired method.

Here is a good reference on CORS:

http://www.w3.org/TR/cors/

Reverse Proxy

This is when you create a proxy between your javascript and the service such that the proxy is hosted in the same domain as the javascript. The javascript call to the service is then modified to be a call to the proxy and since the proxy is in the same domain as the javascript, it does not throw a cross domain error. The proxy will be responsible for calling the actual service on another domain, getting the response and then passing back the response to the javascript. The proxy can be a simple servlet or even a server like Apache or IIS can be configured to act as a pass through proxy.

Here is how you can configure the Apache server on a MAC (we are going to use the Apache server which comes installed by default on the latest MAC OS X versions) to act as a passthrough proxy:

Go to Terminal and type in

$ sudo nano /etc/apache2/httpd.conf

In the httpd.conf file, add the 3 lines highlighted below:

Listen 80

ProxyRequests off

ProxyPassMatch /<keyword>/(.*) <destination service domain>/$1

SSLProxyEngine On

Hit Ctrl+O to write out your changes to the conf file. Hit Enter. Hit Ctrl+X to exit.

Restart your apache server from the Terminal:

 $ sudo apachectl -k restart

The important line here is

ProxyPassMatch /<keyword>/(.*) <destination service url>/$1

This essentially means that when you make a call to this local Apache server in your javascript code with a url like

http://localhost:80/<…>/<keyword>/<rest_of_the_path&gt;

the server will act as a proxy and make a call to

<destination service url>/<rest_of_the_path>

and return back the response from the service call to the javascript.

Using this ProxyPassMatch, we are limiting the Apache server to only act as a proxy for the url calls that have the pattern ‘/<keyword>/’ and to append anything after ‘/<keyword>/’ to the destination url.

For more details on creating a reverse proxy, please refer:

http://overwatering.org/blog/2012/04/reverse-proxy-javascript-app/

In addition, I still haven’t found a reasonable explanation as to why the same-origin policy won’t affect a native app running javascript in a javascript engine or a hybrid app running it in a web view:

http://stackoverflow.com/questions/21143963/why-doesnt-same-domain-policy-affect-native-mobile-apps

If you have a good explanation, please do post it in the comments.

Advertisements

HTML5 – Clocks

My another Github project that I published during my learning phase of HTML5 (I am still learning) was a simple clock demo. It displays an analog and a digital clock. Works great on mobile web browsers as well. It uses the HTML5 canvas element and javascript apis to render.

Here is the link to the Github project: https://github.com/hetalv985/Clocks

The project is available for free under the MIT license.

Feel free to leave your feedback and suggestions.