2014-02-18 3 views
5

Я пытаюсь передать объект JSON моему контроллеру Spring MVC, но я получаю ошибку Access-Control-Allow-Origin.Ошибка Access-Control-Allow-Origin в Spring MVC + Zepto POST

Мой контроллер:

@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" : "[email protected]" , "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"); 
     } 
    }); 
}; 

Я попытался с не stringify в запросе POST, без заголовков в @RequestMapping.

Мой результат:

ВАРИАНТА http://127.0.0.1:8080/AgenceVoyage/user/add 'Access-Control-Allow-Origin' Нет заголовок присутствует на запрашиваемом ресурса. Origin 'http://localhost:9000' поэтому не разрешено доступ. zepto.min.js: 2 XMLHttpRequest не может загрузить

+0

Пожалуйста, проверьте этот ответ. Http: // StackOverflow.com/questions/24098132/no-access-control-allow-origin-header-is-present-on-the-request-resource/25707820 # 25707820 – Aalkhodiry

ответ

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> 

и все!

2

Это потому, что страница загружается с сервера в http://localhost:9000, и эта страница пытается получить доступ через AJAX запроса другой домен http://127.0.0.1:8080/AgenceVoyage/user/add.

Обратите внимание, что разные номера портов заставляют эти два URL-адреса соответствовать двум различным доменам, даже жестко они оба являются URL-адресами localhost.

Поскольку эти два объекта считаются разными доменами, браузер ajax Same Origin Policy запускает и предотвращает выполнение запроса из-за соображений безопасности (запросы ajax для сторонних доменов запрещены).

См. Здесь более подробную информацию о ajax Same Origin Policy, особенно в разделе политики определения происхождения, где указано, что номер порта является частью источника.

+0

Любое решение fort résolve it? Я видел jsonp? – Lombric

+0

Простейшим является серверная страница из того же домена. используя внешний сервер, такой как nginx или apache, WAR могут все еще работать на отдельных серверах. JSONP обычно используется для общедоступных данных, таких как карты, поскольку его трудно защитить http://security.stackexchange.com/questions/23438/security-risks-with-jsonp. CORS - это современная альтернатива http://enable-cors.org/ –

+0

Это часть решения, вы можете принять альтернативу на своем сервере Spring, я подробно описал ее в следующем ответе. – Lombric

0

Если приложение настроено программно, то вам необходимо следующий код в 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() {} 

}