We have CORS issue with rest service hosted in Adobe CQ (Please note that this is a proof of concept application only). To fix this, we have added a simple filter to set required response headers. The code for the filter is some thing like
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
if (request instanceof SlingHttpServletRequest
&& response instanceof SlingHttpServletResponse) {
SlingHttpServletRequest slingRequest = (SlingHttpServletRequest) request;
SlingHttpServletResponse slingResponse = (SlingHttpServletResponse) response;
slingResponse.addHeader("Access-control-Allow-Origin", "*");
slingResponse.addHeader("Access-control-Allow-Methods", "PUT, GET, POST, DELETE, OPTIONS");
slingResponse.addHeader("Access-Control-Allow-Headers", "Content-Type");
filterChain.doFilter(slingRequest, slingResponse);
}
We are using a Jquery script to fire a GET request to the CQ Service to get some JSON value produced by Jercy (MOXY).
$(function(){
$("#getPerson").on("click", function(){
$.ajax({
url: "http://san.dev.local.com:4502/services/person/get",
type: "GET", crossDomain: true,
contentType: "application/json",
cache: false,
dataType: "json",
success: function (data) {
alert('success');
if($.trim(data) == "false") {
alert("Fail to recive");
}
else {
alert("Successfully data recived");
}
} ,error : function(err){
console.log(err);
alert("Error : "+err);
//YOUR CODE FOR AJAX FAILURE
}
});
});
});
[But the accept header of the ajax request shows "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8]" is this ok?]
Note: Our service/Resource is annotated with
@Path("/get")
@GET
@Produces({MediaType.APPLICATION_XML,MediaType.APPLICATION_JSON,MediaType.TEXT_XML})
public Person getPerson() {
.......................
.......................
}
But whenever we send an AJAX request, to get person data we are getting a CORS error
04:46:47.497 Cross-Origin Request Blocked: The Same Origin Policy disallows reading the
remote resource at http://san.dev.local.com:4502/services/person/get?_=1442467869174.
(Reason: CORS request failed).1 <unknown>
Note:
We have used an intercepting proxy to examine the request and response (OWASP ZAP).
Request
OPTIONS http://san.dev.local.com:4502/services/person /get?_=1442467869171 HTTP/1.1
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:40.0) Gecko/20100101 Firefox/40.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Origin: http://san.dev.local.com:8080
Access-Control-Request-Method: GET
Access-Control-Request-Headers: content-type
Connection: keep-alive
Host: san.dev.local.com:4502
Response
HTTP/1.1 200 OK
Connection: Keep-Alive
Server: Day-Servlet-Engine/4.1.52
Content-Type: text/html
Content-Length: 0
Date: Thu, 17 Sep 2015 05:32:24 GMT
Allow: GET,OPTIONS,HEAD
Surprisingly, the response header
Access-control-Allow-Origin
is missing in the response.
Any pointers to solve this issue is greatly appreciated.
For me it seems that some or the other filter is overriding our settings. If so, is there a way to handle this scenario.
Just now we found this post : Java filter failing to set response headers.
Modified the filder properties by adding a service ranking property to keep the filter up in the possibel stack.
@Properties({ @Property(name = "filter.scope", label = "scope", value = "REQUEST"),
@Property(name = "filter.order", label = "order", value = "2"),
@Property(name = "service.ranking", intValue = 1)})
But this also not helped us. Any pointers will be helpful for us.
Thanks in advance, San
You already know the reason you are getting the CORS error is because there is no Access-Control-Allow-Origin:* value in your response header. In you filter servlet have you tried specifying a specific domain (ex. http://san.dev.local.com:8080)?
You could also try creating a regular servlet and see if the headers are returned.
The filtering should be chained. Maybe add a custom response header value (myvar: success) to make sure it's being returned from your filter. You could always hook up a debugger to see what the call stack looks like and potentially figure out what other filters are being used.