【问题标题】:'Access-Control-Allow-Origin' error in Spring MVC + Zepto POSTSpring MVC + Zepto POST 中的“Access-Control-Allow-Origin”错误
【发布时间】:2014-03-18 19:39:18
【问题描述】:

我正在尝试将一个 JSON 对象发布到我的 Spring MVC 控制器,但我只收到一个 Access-Control-Allow-Origin 错误。

我的控制器:

@RequestMapping(value= "/add", method = RequestMethod.POST, headers = {"content-type=application/json"})
public @ResponseBody Reponse addUser(Model model, @RequestBody @Valid @ModelAttribute("user") User user, BindingResult result) {
    if (result.hasErrors()) {
        Reponse error = new Reponse();
        // etc......
        return error;
    } else {
        return service.addUser(user);
    }
}

我的 Zepto 帖子:

this.addUser = function (valeur, callback) {
    $.ajax({
        type: 'POST',
        url: 'http://127.0.0.1:8080/AgenceVoyage/user/add',
        data: JSON.stringify({"mail" : "toto@toto.fr" , "password" : "titi"}),
        dataType: "json",
        contentType: "application/json",

        success: function(data) {
            if(data.reponse == "OK") {
                window.location = "main.html";
            } else {
                alert("PROBLEM");
            }
        },

        error: function(xhr, type) {
            alert("ERROR");
        }
    });
};

我尝试在 POST 请求中不使用字符串化,@RequestMapping 中没有标头。

我的结果:

选项http://127.0.0.1:8080/AgenceVoyage/user/add 否 请求中存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点“http://localhost:9000” 使用权。 zepto.min.js:2 XMLHttpRequest 无法加载

【问题讨论】:

标签: ajax spring spring-mvc post zepto


【解决方案1】:

我找到了解决方案:

首先,创建一个新的过滤器,它将设置标题响应:

    @Component
public class SimpleCORSFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {}

    public void destroy() {}

}

之后,在您的 web.xml 中添加这些行:

 <filter>
  <filter-name>cors</filter-name>
  <filter-class>MY.PACKAGE.SimpleCORSFilter</filter-class>
 </filter>

 <filter-mapping>
  <filter-name>cors</filter-name>
  <url-pattern>/*</url-pattern>
 </filter-mapping>

就是这样!

【讨论】:

    【解决方案2】:

    这是因为该页面是从http://localhost:9000 中的服务器加载的,并且该页面正试图通过 ajax 请求访问不同的域 http://127.0.0.1:8080/AgenceVoyage/user/add

    请注意,不同的端口号使得这两个 url 对应于两个不同的域,即使它们都是 localhost url。

    因为这两个被认为是不同的域,浏览器 ajax 同源策略启动并由于安全原因阻止请求被执行(不允许针对第三方域的 ajax 请求)。

    有关 ajax Same Origin Policy 的更多详细信息,请参阅此处,特别是在原点确定策略部分中提到端口号是原点的一部分。

    【讨论】:

    • 最简单的是从同一个域服务器页面。使用像 nginx 或 apache 这样的前端服务器,WAR 仍然可以在单独的服务器上运行。 JSONP 通常用于地图等公共可用数据,因为它很难保护security.stackexchange.com/questions/23438/…。 CORS 是现代替代品enable-cors.org
    • 这是解决方案的一部分,您可以在您的 Spring 服务器上采用替代方案,我在下一个响应中详细说明。
    【解决方案3】:

    如果您的应用程序是以编程方式配置的,那么您需要在 WebApplicationInitializer 实现中使用下一个代码,而不是“xml”:

    public class WebAppInitializer implements WebApplicationInitializer {
    
      @Override
      public void onStartup(ServletContext servletContext) {
          ... // your context configuration like in Spring.io tutorial
    
         // Register filter to allow cross-domain requests
         registerServletFilter(servletContext, new SimpleCORSFilter());
      }
    
      ...
    
      protected FilterRegistration.Dynamic registerServletFilter(ServletContext servletContext, Filter filter) {
        String filterName = Conventions.getVariableName(filter);
        FilterRegistration.Dynamic registration = servletContext.addFilter(filterName, filter);
        registration.setAsyncSupported(true);
        registration.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
        return registration;
      }
    }
    

    如果过滤器是

    @Component
    public class SimpleCORSFilter implements Filter {
    
      public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
       response.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept");
        chain.doFilter(req, res);
      }
    
      public void init(FilterConfig filterConfig) {}
    
      public void destroy() {}
    
    }
    

    【讨论】:

      【解决方案4】:

      在控制器类中插入此注解@CrossOrigin

      @CrossOrigin(origin = "http://domain2.com", maxAge = 3600)
      @RestController
      @RequestMapping("/account")
      public class UserController {
      
      }
      

      字体: https://dzone.com/articles/cors-support-spring-framework

      【讨论】:

        猜你喜欢
        • 2023-01-13
        • 1970-01-01
        • 2018-12-12
        • 2013-09-14
        • 2017-06-15
        • 2017-06-15
        • 2019-04-13
        • 2014-03-05
        • 1970-01-01
        相关资源
        最近更新 更多