3

This question has been asked numerous times, but I fail to find an answer for my situation with React on the client, using SockJS and Spring Boot v2.2.0.RELEASE on the backend.

Just to be clear, I am using Websockets only!

org.springframework.boot:spring-boot-starter-websocket

All solutions I find are for older versions of Spring Boot, or just for Spring. Or just for regular web.

Here is my WebSocketConfig

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
  @Override
  public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    System.out.println("WebSocketConfig.registerWebSocketHandlers");
    registry.addHandler(new WebSocketHandler(), "/sockjs").setAllowedOrigins("*").withSockJS();
  }
}

When I use a sample static HTML page + some Javascript code in the Spring Boot application it works fine (coming from the same :8080 domain), so I know this is strictly a CORS issue.

When I run my sample React application with this code:

componentDidMount() {
  const url = 'http://localhost:8080/sockjs';
  const options = {};
  let sockjs = new SockJS(url, /*_reserved*/null, options);

  sockjs.onopen = function () {
    console.log('sockJS endpoint OPENED OK');
    this.setState({ socket: sockjs });
  }; 
}

Since I come from localhost:3000 (the React dev server), it logs the error message:

Access to XMLHttpRequest at 'http://localhost:8080/sockjs/info?t=1572983410738' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Do I have to do anything more than .setAllowedOrigins("*") in my WebSocketConfig?

My suspicion is that I need to setup something else, since the websocket protocol starts with a regular connection that is later "upgraded" to websockets.

--- UPDATE --- I have concluded that this has something to do with the SockJS library. When I remove it, like this:

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
    System.out.println("WebSocketConfig.registerWebSocketHandlers");
    registry.addHandler(myHandler(), "/sockjs").setAllowedOrigins("*"); // .withSockJS();;
}

and create a simple websocket client without sockjs, something like this:

var webSocketURL = null;
webSocketURL = protocol + "://" + hostname + ":" + port + endpoint;
console.log("openWSConnection::Connecting to: " + webSocketURL);
try {
  webSocket = new WebSocket(webSocketURL);
  webSocket.onopen = function(openEvent) {
      console.log("WebSocket OPEN: " + JSON.stringify(openEvent, null, 4));
}

then it works as expected. When I change the .setAllowedOrigins call I get the right result. I get 403 when it doesnt match, and when it matches I can open the websocket.

Now I need to find out what sockJS does that stops this!

Peter Andersson
  • 1,947
  • 3
  • 28
  • 44
  • I had exactly the same issue and [this](https://stackoverflow.com/a/52385783/5079412) helped me. Check it out – evuazeze Dec 29 '19 at 08:26
  • @Peter Andersson it works because you use `ws:` protocol with the native WebSocket library instead of those http polyfills/fallbacks. I managed to get it to work with that as well and avoid CORS. I think the ws protocol is not covered by those CORS restrictions like HTTP is – xetra11 Oct 21 '21 at 22:27

0 Answers0