Cross-Origin Request Blocked Spring REST service + AJAX

前端 未结 3 959
闹比i
闹比i 2021-01-02 18:21

Unable to call spring REST service

My spring service

@RequestMapping(value = \"/MAS/authenticate\", method = RequestMethod.POST)
public ResponseEnti         


        
相关标签:
3条回答
  • 2021-01-02 18:41

    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.

    0 讨论(0)
  • 2021-01-02 19:01

    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. :)

    0 讨论(0)
  • 2021-01-02 19:02

    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
    }
    
    0 讨论(0)
提交回复
热议问题