Kunal Jaggi, Author of SCWCD Exam Guide with Java EE 5 and Programming, WebSphere MQ with Java, McGraw-Hill Education
If you have worked with an AJAX based application for sometime, chances are that you have come across situations when the browser did not allow cross-domain request. This is a security feature which is imposed by web browsers. It is commonly referred as “same origin policy”. Put in simple terms, this means that pages originating from mars.com can't access data from venus.com. This security feature is built into XMLHttpRequest. As shown in Figure 1 below, browsers prevent you from making XMLHttpRequest to domains other than the original domain the page was served from.
In this article, we will show a new technique introduced in HTML 5 specification which can help us bypass this restriction.
Application setup
We have done most of the heavy lifting for this article. We have deployed two mobile web applications to Google App Engine (GAE). The first web app (pcq-mobile.appspot.com) will make a POST request to a different web application (pc-quest.appspot.com). Using CORS, the second website (pc-quest.appspot.com) will allow its resources to be accessed by a web page from a different domain. As discussed before, if you use vanilla XMLHTTPRequest, your browser's security policy will block access and you will get an error message, as shown before in Figure 1 above.
Figure 2 shows the feedback page we will submit via CORS to a JSP page hosted on a different domain.
Thanks to CORS, cross-domain requests are now possible with the introduction of XMLHttpRequest version 2. Note that CORS is part of the HTML 5 standard which is still under development. That said, support for CORS is available across a wide range of modern web browsers. We used Safari and Chrome for demonstration purpose.
Configuring CORS Server
To begin with, before we initiate a CORS request, we need to configure the server to support HTTP request originating from different domains. A CORS server needs to add certain HTTP response header to enable cross-origin requests. In this example, we will configure CORS in the second app which provides resources. We will use a CORS filer, a Java Servlet filter based solution available at http://software.dzhuvinov.com. Configuring the filter is very easy, you need to drop the JAR file under WEB-INF/lib directory and edit Web application Deployment Descriptor (DD) file- web.xml to enable filter before the request can be serviced by the JSP page. You can find detailed instructions at http://software.dzhuvinov.com/cors-filter-installation.html. For demonstration, we have already configured CORS on pc-quest.appspot.com which hosts the JSP page to process user feedback form submission.
Initiation a CORS request is tad easy, there are no special methods. You can continue using the XMLHttpRequest object the way you used before. If CORS is supported by the web browser, the XMLHttpRequest object will have withCredentials property already set. Code snippet presented in Listing 1 shows a simple client-side validation to check if the browser supports cross-origin requests.
Alternatively, since jQuery automatically supports CORS, you can check the support using jQuery.support.cors. This will return a boolean true value if the browser supports CORS request, else you will get a false. Enter some values and submit the form, the output is shown in Figure 3 below.
Per the specification, a valid CORS request should have a request header called Origin. The Origin request header is automatically added by a supported web browser. Figure 4 depicts the request header.
As depicted, the value of Origin header is scheme, domain and port from which the request originates. In our example, it is http://pcq-mobile.appspot.com. Note that port is included only if it is not a default port.
The CORS response also has three special headers, as depicted in Figure 5 below.
Access-Control-Allow-Origin is a mandatory header which identifies origin which is allowed to make CORS request. CORS supports the se of a wildcard “*” to allow requests from any origin. Access-Control-Expose-Headers include the headers we want to expose to the client.
Prior to CORS, web developers used other tricks and workarounds like JSON-P (JSON with Padding) which dynamically imports JavaScript from a different domain. That being said, JSON-P has limited use because of security concerns and it supports only HTTP GET operation. CORS on the other hand, provides a much refined and better gateway to cross-domain requests by supporting a wide variety of HTTP operations. Since CORS falls under HTML umbrella of technologies, it's not fully implemented across all browsers. Most modern web browsers do support CORS except Opera and partial support is available in IE version 8 and 9. Note that with IE 8 and 9, you can use XDomainRequest as a workaround.
Making a CORS Request
Examining CORS Headers
Conclusion