Monday, August 19, 2013

Httpheaders to enable CORS filter for REST service used by dojo jsonrest data store

Dojo jsonrest datastore provides a simple way to implement ajax communication between dojo data grid (datagrid, enhancegrid, dgrid, or ondemandgrid) and the web service provider.
However, most times people would face CORS access issue when using jsonrest api.
Here's a few key points for the server side to enable the connection with jsonrest:
1. Access-Control-Allow-Origin, this header defines the allowed originate json request client. If not set, errors like "origin not allowed" will be thrown.
2. Access-Control-Allow-Headers, this header defines the allowed requesting headers, such as X-Requested-With, X-Range, Range, and so on. If not set, errors like "header not allowed" will be thrown.
3. Access-Control-Expose-Headers, this header defines the allowed response headers, such as Content-Range. If not set, error like "refused unsafe header" will be thrown.
X-Requested-With, X-Range, Range, Content-Range are the key headers attributes for jsonrest api to communciate with the server. They have to be enabled in the http header.

In order to enable them, we need to add/set a few headers from server side programmatically. Using java servlet/tomcat as an example, we can use server side filter to achieve this.
There's existing CORS filter library available at http://software.dzhuvinov.com/cors-filter-installation.html . However, it didn't work well for me. Implementing a custom CORS filter isn't that difficult as well. Here's the code:
public class CorsFilter implements Filter {

public CorsFilter() { }
public void init(FilterConfig fConfig) throws ServletException { }
public void destroy() { }
public void doFilter(
ServletRequest request, ServletResponse response, 
FilterChain chain) throws IOException, ServletException {
HttpServletResponse res=(HttpServletResponse)response;
res.addHeader("Access-Control-Allow-Origin", "*");
if(res.getHeader("Access-Control-Allow-Headers")==null) {
res.addHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-Range, Range, Content-Type, Accept");
}else{
res.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, X-Range, Range, Content-Type, Accept,"+res.getHeader("Access-Control-Allow-Headers"));
}
res.addHeader("Access-Control-Expose-Headers","Accept-Ranges, Content-Encoding, Content-Length, Content-Range");
chain.doFilter(request, response);
}
}
 After configuring this filter to apply to all requesting paths, it'll for sure enable those dojo jsonrest headers.
Please feel free to comment on whether there's easier ways to do this.

No comments: