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!