【问题标题】:Header Access-Control-Allow-Origin:* not working properly on Spring MVC标头 Access-Control-Allow-Origin:* 在 Spring MVC 上无法正常工作
【发布时间】:2013-04-08 06:59:48
【问题描述】:

我有一个使用 RESTful Web 服务在 Spring MVC 上运行的 Web 应用程序。我正在尝试从 HTML/Javascript 文件向这些 Web 服务发送 JSON。这是Javascript:

$.ajax
(
{
    type: "post",
    data: JSON.stringify(data),
    contentType : "application/json",
    dataType: "json",
    url: "http://localhost/proj/service",
    success: function(data) 
    {
        callback(data);
    }
}
);

以及 Spring MVC 中的映射:

@RequestMapping(value = "/proj/service/", method = RequestMethod.POST)  
    public ModelAndView procRequest(@RequestBody String paramsJson, HttpServletResponse resp, WebRequest request_p){        

        resp.setStatus(HttpStatus.CREATED.value());
        resp.setHeader("Location", request_p.getContextPath() + "/proj/service");
        resp.addHeader("Access-Control-Allow-Origin", "*"); 
            //Code
}

由于某种原因,当我从它通过的 ajax 请求中删除 contentType 键时,它的格式当然不正确,因为我希望 Javascript 向我发送 JSON 字符串。但由于某种原因,如果我留下 contentType 键,我会收到以下错误:

XMLHttpRequest cannot load http://localhost:8080/proj/service/. Origin http://localhost is not allowed by Access-Control-Allow-Origin. 

我不知道什么可能导致这个错误,因为适当的标题在那里。

谢谢。

【问题讨论】:

    标签: javascript jquery rest spring-mvc cors


    【解决方案1】:

    Content-Type 标头触发 CORS 预检请求。您需要修改您的处理程序以响应具有以下标头的OPTIONS 请求:

    resp.addHeader("Access-Control-Allow-Origin", "*");
    resp.addHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
    resp.addHeader("Access-Control-Allow-Headers", "Content-Type");
    

    这应该向预检请求发送适当的响应,之后浏览器将发出实际请求。您可以在此处了解有关预检请求的更多信息:http://www.html5rocks.com/en/tutorials/cors/

    【讨论】:

    • 它看起来不像是预检请求的问题,因为它会在跟踪中明确显示,否则 OPTIONS 方法会失败。
    • @plus,您指的是哪个跟踪?无论预检失败还是实际请求失败,浏览器控制台日志中的错误看起来都是一样的。
    • 因为当您遇到预检问题时,您会收到两个错误:OPTIONS http://foo/bar Origin http://foo is not allowed by Access-Control-Allow-Origin. 然后XMLHttpRequest cannot load http://foo/bar. Origin http://foo is not allowed by Access-Control-Allow-Origin.
    • 您使用的是哪个浏览器?我没有在我的浏览器中看到它。如果预检失败,实际请求永远不会通过,所以无论如何都应该有一个请求。
    • 我正在使用 Chrome。如果缺少请求的标头或方法,他们可能会添加它以给出更具体的错误。
    【解决方案2】:

    我是这样做的:

        @RequestMapping("/listActions")
    public @ResponseBody List<Action> list(HttpServletRequest request, HttpServletResponse response) {
        response.addHeader("Access-Control-Allow-Origin", "*");
        response.addHeader("Access-Control-Allow-Methods", "GET,PUT,POST,DELETE");
        response.addHeader("Access-Control-Allow-Headers", "Content-Type");
    
        List<Action> actions =  new ArrayList<Action>();
        actions.add(new Action(1, "Do something fantastic"));
        actions.add(new Action(2, "Save the world"));
        actions.add(new Action(3, "Buy beer"));
        actions.add(new Action(4, "Butcher a hog"));
        return actions;
    }
    

    【讨论】:

      猜你喜欢
      • 2016-08-31
      • 2021-09-15
      • 1970-01-01
      • 2021-12-02
      • 1970-01-01
      • 2016-01-11
      • 2018-01-24
      • 2018-06-21
      • 2016-05-07
      相关资源
      最近更新 更多