2016-06-16 365 views
2

我想實現使用SpringSockets在後端和前端我使用sockjs,踐踏和角2的websockets。當我試圖連接sockjs與春天,我得到以下錯誤SockJS客戶端與春季WebSocket - CORS

在瀏覽器控制檯:

stomp.min.js:8 Opening Web Socket... 
sockjs.min.js:2 WebSocket connection to 'ws://localhost:8080//holmes-web/hello/501/c4oj5wjv/websocket' failed: Error during WebSocket handshake: Unexpected response code: 500 
zone.js:101 POST http://localhost:8080//holmes-web/hello/501/rpawmcjq/xhr_streaming?t=1466104769153 scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM1433:3r._start @ sockjs.min.js:2(anonymous function) @ sockjs.min.js:2ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ core.umd.js:6066ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423 
:3000/#/sockjs-test:1 XMLHttpRequest cannot load http://localhost:8080//holmes-web/hello/501/rpawmcjq/xhr_streaming?t=1466104769153. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 403. 
about:blank:1 Refused to display 'http://localhost:8080//holmes-web/hello/iframe.html#kydolgh3' in a frame because it set 'X-Frame-Options' to 'DENY'. 
about:blank:1 Refused to display 'http://localhost:8080//holmes-web/hello/iframe.html#42qmp3pf' in a frame because it set 'X-Frame-Options' to 'DENY'. 
zone.js:101 POST http://localhost:8080//holmes-web/hello/501/krvk3vgm/xhr?t=1466104770537 scheduleTask @ zone.js:101ZoneDelegate.scheduleTask @ zone.js:336Zone.scheduleMacroTask @ zone.js:273(anonymous function) @ zone.js:122send @ VM1433:3r._start @ sockjs.min.js:2(anonymous function) @ sockjs.min.js:2ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ core.umd.js:6066ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423 
:3000/#/sockjs-test:1 XMLHttpRequest cannot load http://localhost:8080//holmes-web/hello/501/krvk3vgm/xhr?t=1466104770537. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 403. 
about:blank:1 Refused to display 'http://localhost:8080//holmes-web/hello/iframe.html#0u5cuqn2' in a frame because it set 'X-Frame-Options' to 'DENY'. 
sockjs.min.js:3 GET http://localhost:8080//holmes-web/hello/501/z2a5f4hz/jsonp?c=_jp.a2cgyca r._createScript @ sockjs.min.js:3r @ sockjs.min.js:2n._scheduleReceiver @ sockjs.min.js:2n @ sockjs.min.js:2n @ sockjs.min.js:2r @ sockjs.min.js:2r._connect @ sockjs.min.js:2r._transportClose @ sockjs.min.js:2r._transportTimeout @ sockjs.min.js:2ZoneDelegate.invokeTask @ zone.js:356onInvokeTask @ core.umd.js:6066ZoneDelegate.invokeTask @ zone.js:355Zone.runTask @ zone.js:256ZoneTask.invoke @ zone.js:423 
stomp.min.js:8 Whoops! Lost connection to http://localhost:8080//holmes-web/hello 

在後端控制檯:

Jun 17, 2016 1:08:48 AM org.apache.catalina.core.StandardWrapperValve 

invoke 
SEVERE: Servlet.service() for servlet [holmes] in context with path [/holmes-web] threw exception [Request processing failed; nested exception is org.springframework.web.socket.sockjs.SockJsException: Uncaught failure in SockJS request, uri=http://localhost:8080//holmes-web/hello/544/feziyojb/jsonp?c=_jp.a24dbmq; nested exception is org.springframework.web.socket.sockjs.SockJsException: Uncaught failure for request http://localhost:8080//holmes-web/hello/544/feziyojb/jsonp?c=_jp.a24dbmq; nested exception is java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container] with root cause 
java.lang.IllegalArgumentException: Async support must be enabled on a servlet and for all filters involved in async request processing. This is done in Java code using the Servlet API or by adding "<async-supported>true</async-supported>" to servlet and filter declarations in web.xml. Also you must use a Servlet 3.0+ container 
    at org.springframework.util.Assert.isTrue(Assert.java:65) 
    at org.springframework.http.server.ServletServerHttpAsyncRequestControl.<init>(ServletServerHttpAsyncRequestControl.java:58) 
    at org.springframework.http.server.ServletServerHttpRequest.getAsyncRequestControl(ServletServerHttpRequest.java:213) 
    at org.springframework.web.socket.sockjs.transport.session.AbstractHttpSockJsSession.handleInitialRequest(AbstractHttpSockJsSession.java:200) 
    at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequestInternal(AbstractHttpSendingTransportHandler.java:68) 
    at org.springframework.web.socket.sockjs.transport.handler.JsonpPollingTransportHandler.handleRequestInternal(JsonpPollingTransportHandler.java:79) 
    at org.springframework.web.socket.sockjs.transport.handler.AbstractHttpSendingTransportHandler.handleRequest(AbstractHttpSendingTransportHandler.java:58) 
    at org.springframework.web.socket.sockjs.transport.TransportHandlingSockJsService.handleTransportRequest(TransportHandlingSockJsService.java:256) 
    at org.springframework.web.socket.sockjs.support.AbstractSockJsService.handleRequest(AbstractSockJsService.java:328) 
    at org.springframework.web.socket.sockjs.support.SockJsHttpRequestHandler.handleRequest(SockJsHttpRequestHandler.java:90) 
    at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51) 
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) 
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) 
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966) 
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:857) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:624) 
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842) 
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:209) 
    at com.thetransactioncompany.cors.CORSFilter.doFilter(CORSFilter.java:244) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:330) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:118) 
    at org.springframework.security.web.access.intercept.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:84) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.access.ExceptionTranslationFilter.doFilter(ExceptionTranslationFilter.java:113) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.session.SessionManagementFilter.doFilter(SessionManagementFilter.java:103) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.AnonymousAuthenticationFilter.doFilter(AnonymousAuthenticationFilter.java:113) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.servletapi.SecurityContextHolderAwareRequestFilter.doFilter(SecurityContextHolderAwareRequestFilter.java:154) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.savedrequest.RequestCacheAwareFilter.doFilter(RequestCacheAwareFilter.java:45) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.www.BasicAuthenticationFilter.doFilter(BasicAuthenticationFilter.java:150) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.csrf.CsrfFilter.doFilterInternal(CsrfFilter.java:85) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50) 
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
    at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342) 
    at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192) 
    at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160) 
    at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:344) 
    at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:261) 
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241) 
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:423) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1079) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:316) 
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
    at java.lang.Thread.run(Thread.java:745) 

我的配置類是 WebSocketConfig

@Configuration 
@EnableWebSocketMessageBroker 
public class WebSocketConfig extends AbstractWebSocketMessageBrokerConfigurer { 

    @Override 
    public void configureMessageBroker(MessageBrokerRegistry config) { 
     config.enableSimpleBroker("/topic"); 
     config.setApplicationDestinationPrefixes("/app"); 
    } 

    @Override 
    public void registerStompEndpoints(StompEndpointRegistry registry) { 
     registry.addEndpoint("/hello").withSockJS(); 
    } 

} 

MvcWebApplicationInitializer

public class MvcWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { 

@Override 
    protected void customizeRegistration(ServletRegistration.Dynamic registration) { 
    registration.setInitParameter("dispatchOptionsRequest", "true"); 
    registration.setAsyncSupported(true); 
    } 

@Override 
protected Class<?>[] getRootConfigClasses() { 
    return new Class[] { SecurityConfiguration.class, WebSocketConfig.class }; 
} 

@Override 
protected Class<?>[] getServletConfigClasses() { 
    // TODO Auto-generated method stub 
    return new Class<?>[] { WebConfig.class }; 
} 

@Override 
protected String[] getServletMappings() { 
    // TODO Auto-generated method stub 
    return new String[] { "/" }; 
} 

// ...其他替代... }

的web.xml

<?xml version="1.0" encoding="UTF-8"?> 


<web-app 
     version="3.0" 
     xmlns="http://java.sun.com/xml/ns/javaee" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 
    <display-name>Holmes</display-name> 

    <!-- <filter> 
     <filter-name>CorsFilter</filter-name> 
     <filter-class>org.apache.catalina.filters.CorsFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>CorsFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 

    <filter> 
     <filter-name>CORSFilter</filter-name> 
     <filter-class>com.beehyv.holmes.filters.CORSFilter</filter-class> 
    </filter> 
    <filter-mapping> 
     <filter-name>CORSFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping>--> 
    <filter> 
     <!-- The CORS filter with parameters --> 
     <filter-name>CORS</filter-name> 
     <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class> 
     <async-supported>true</async-supported> 

     <init-param> 
      <param-name>cors.allowGenericHttpRequests</param-name> 
      <param-value>true</param-value> 
     </init-param> 

     <init-param> 
      <param-name>cors.allowOrigin</param-name> 
      <param-value>*</param-value> 
     </init-param> 

     <init-param> 
      <param-name>cors.allowSubdomains</param-name> 
      <param-value>false</param-value> 
     </init-param> 

     <init-param> 
      <param-name>cors.supportedMethods</param-name> 
      <param-value>GET, HEAD, POST, GET, PUT, OPTIONS</param-value> 
     </init-param> 

     <init-param> 
      <param-name>cors.supportedHeaders</param-name> 
      <param-value>*</param-value> 
     </init-param> 

     <init-param> 
      <param-name>cors.exposedHeaders</param-name> 
      <param-value>X-Test-1, X-Test-2</param-value> 
     </init-param> 

     <init-param> 
      <param-name>cors.supportsCredentials</param-name> 
      <param-value>true</param-value> 
     </init-param> 

     <init-param> 
      <param-name>cors.maxAge</param-name> 
      <param-value>3600</param-value> 
     </init-param> 

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

</web-app> 
+0

您正在使用哪個容器+版本?您是否可以禁用所有過濾器和安全性來檢查問題是否仍然存在? –

+0

@BrianClozel,我試着禁用所有的過濾器。只有過濾器,我使用的是CORsfilter,如果我禁用,我得到一個cors錯誤。我想這個問題不是用過濾器配置,而是用spring套接字中的異步配置。 – Roy

回答

0

在您的web.xml中,您必須將您的servlet添加爲true。不僅適用於過濾器,也適用於servlet。 示例:

<servlet> 
    <servlet-name>appServlet</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value> 
      /WEB-INF/spring/appServlet/servlet-context.xml 
     </param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
    <async-supported>true</async-supported> 
</servlet>