Spring MVC + Zepto POST中出现“Access-Control-Allow-Origin”错误

时间:2014-02-18 20:03:53

标签: ajax spring spring-mvc post zepto

我正在尝试将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 POST:

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请求中没有stringify,@RequestMapping中没有标题。

我的结果:

  

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

4 个答案:

答案 0 :(得分:9)

我找到了解决方案:

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

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

那一切!

答案 1 :(得分:2)

这是因为页面是从http://localhost:9000中的服务器加载的,此页面正在尝试通过ajax请求访问另一个域http://127.0.0.1:8080/AgenceVoyage/user/add

请注意,不同的端口号使这两个网址对应两个不同的域,即使它们都是本地主机网址也很难。

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

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

答案 2 :(得分:0)

如果您的应用程序是以编程方式配置的,那么您需要WebApplicationInitializer实施中的下一个代码,而不是&#39; xml&#39;:

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() {}

}

答案 3 :(得分:0)

在控制器类

中插入此注释@CrossOrigin
@CrossOrigin(origin = "http://domain2.com", maxAge = 3600)
@RestController
@RequestMapping("/account")
public class UserController {

}

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