有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java跨源请求阻止Spring REST服务+AJAX

无法呼叫spring REST服务

我的春季服务

@RequestMapping(value = "/MAS/authenticate", method = RequestMethod.POST)
public ResponseEntity<Map<String, String>> authenticate(@RequestBody Subject subject) {
    Map<String, String> result = new HashMap<String, String>();
    result.put("result_detail", "Invalid Password");
    result.put("result", "failure");
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setContentType(MediaType.APPLICATION_JSON);
    responseHeaders.add("Access-Control-Allow-Origin", "*"); // also added header to allow cross domain request for any domain
    return new ResponseEntity<Map<String, String>>(result, responseHeaders, HttpStatus.OK);
}

我的AJAX代码

$.ajax(
{
  crossDomain: true,
  type: "POST",
  contentType: "application/json; charset=utf-8",
  async: false,
  url: "http://localhost:8080/SpringMVC/rest/MAS/authenticate",
  headers: {"Access-Control-Allow-Origin" : "*"},
  data:{},
  dataType: "json", //also tried "jsonp"
  success: function(data, status, jqXHR)
  {
    alert('success');
  },
  error: function(jqXHR, status)
  {
    alert('error');
  }
});

我发现以下错误:(

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/SpringMVC/rest/MAS/authenticate. This can be fixed by moving the resource to the same domain or enabling CORS.

我也试过了。它将my body对象附加到URL中,从而生成不同的URL,并且无法命中我的服务URL,从而导致404错误

我的浏览器:firefox 36.0.4

我怎样才能摆脱这个错误,有什么帮助吗


共 (3) 个答案

  1. # 1 楼答案

    默认情况下,唯一允许的方法是GET,您不允许在服务器端使用POST

    Access-Control-Allow-Origin: *
    

    此标题仅启用CORS,但您需要添加以下内容:

    Access-Control-Allow-Methods: POST, GET
    

    关于Mozilla项目

    所以你的代码应该是这样的:

    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
    

    更新

    我重新阅读了这篇文章,发现了一些细节:

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

    正如您可以用粗体阅读一样,您必须为数据设置其他Content-Type(当前为contentType: "application/json; charset=utf-8",),或者使用后面描述的飞行前技术:

    • 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)

    因此,我建议您要么更改contentType,要么尝试在请求中使用此标题:

    Access-Control-Request-Headers: X-HEADER_NAME_OF_YOUR_CHOOSE
    

    下面是你的回复:

    Access-Control-Allow-Methods: POST, GET, OPTIONS
    Access-Control-Allow-Headers: X-HEADER_NAME_OF_YOUR_CHOOSE
    

    然后你可以尝试调用你的方法

  2. # 2 楼答案

    以下是跨平台spring boot web服务调用的解决方案

    应用程序URL:http://localhost:8080

    Web服务URL:http://localhost:9090

    在spring控制器中,使用以下注释

    @CrossOrigin(origins = "http://localhost:8080")
    @RequestMapping(value = "/uri", method = RequestMethod.GET)
    public SomeObject someMethod(){
    // your logic will come here
    }
    
  3. # 3 楼答案

    我的AJAX通话和服务还行。在网上搜索了很多之后,我发现它的服务器端问题不是客户端问题

    在Spring的服务器端,我们必须实现允许CORS请求的过滤器

    过滤器将是这样的

    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);
        }
    
    }
    

    在网络上。xml在您的服务请求上应用此筛选器,如下所示

        <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> 
    

    这可能有助于解决此问题的其他人。:)