Cross-Origin Request Blocked Spring REST service + AJAX
My AJAX call and service were OK. After searching a lot on internet i have found that its server side problem not client side.
on server side with Spring we have to implement filter which will allow CORS requests.
filter will look like this.
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.web.filter.OncePerRequestFilter;
public class CORSFilter extends OncePerRequestFilter {
private static final Log LOG = LogFactory.getLog(CORSFilter.class);
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.addHeader("Access-Control-Allow-Origin", "*");
if (request.getHeader("Access-Control-Request-Method") != null && "OPTIONS".equals(request.getMethod())) {
LOG.trace("Sending Header....");
// CORS "pre-flight" request
response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
// response.addHeader("Access-Control-Allow-Headers", "Authorization");
response.addHeader("Access-Control-Allow-Headers", "Content-Type");
response.addHeader("Access-Control-Max-Age", "1");
}
filterChain.doFilter(request, response);
}
}
and in web.xml apply this filter on your service requests like this
<filter>
<filter-name>cors</filter-name>
<filter-class>com.test.common.controller.CORSFilter</filter-class> <!-- your package name and filter class -->
</filter>
<filter-mapping>
<filter-name>cors</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
This may help someone else who went through this problem. :)
By default the only method allowed is a GET
, and you don't allow the POST
on your server side:
Access-Control-Allow-Origin: *
This header only enables CORS, but you need to add this:
Access-Control-Allow-Methods: POST, GET
More detailed how-to about the HTTP access control (CORS)
on Mozilla project
So your code should be something like this:
responseHeaders.add("Access-Control-Allow-Methods", "POST, GET"); // also added header to allow POST, GET method to be available
responseHeaders.add("Access-Control-Allow-Origin", "*"); // also added header to allow cross domain request for any domain
Update:
I have re-read the article, and found out some details:
A simple cross-site request is one that:
- Only uses GET, HEAD or POST. If POST is used to send data to the server, the
Content-Type
of the data sent to the server with the HTTP POST request is one of application/x-www-form-urlencoded, multipart/form-data, or text/plain.- Does not set custom headers with the HTTP Request (such as X-Modified, etc.)
As you can read in bold, you must set other Content-Type
for your data (currently it is contentType: "application/json; charset=utf-8",
) or use the preflight technique described later:
- It uses methods other than GET, HEAD or POST. Also, if POST is used to send request data with a Content-Type other than application/x-www-form-urlencoded, multipart/form-data, or text/plain, e.g. if the POST request sends an XML payload to the server using application/xml or text/xml, then the request is preflighted.
- It sets custom headers in the request (e.g. the request uses a header such as X-PINGOTHER)
So I suggest you either change the contentType or try to work with this header into your request:
Access-Control-Request-Headers: X-HEADER_NAME_OF_YOUR_CHOOSE
and this headers into your response:
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Headers: X-HEADER_NAME_OF_YOUR_CHOOSE
And after that you can try to call your method.
Following is the solution for cross platform spring boot web service call.
Application URL: http://localhost:8080
Webservice URL: http://localhost:9090
In your spring controller use following annotation
@CrossOrigin(origins = "http://localhost:8080")
@RequestMapping(value = "/uri", method = RequestMethod.GET)
public SomeObject someMethod(){
// your logic will come here
}