Angular + Spring 启动 Websocket cors 错误
Angular + Spring boot Websocket cors error
我正在使用 Spring boot 和 Angular 12 在本地开发一个 websocket。我已经阅读了很多教程,但我遇到了一个奇怪的 Cors 错误。
连接套接字的Angular代码如下:
import { Injectable } from '@angular/core';
import { NotificationWebSocket } from '../model/NotificationWebSocket.model';
import { Stomp } from '@stomp/stompjs';
import * as SockJS from 'sockjs-client';
@Injectable({
providedIn: 'root'
})
export class WebsocketService{
stompClient: any;
webSocketEndPoint: string = 'http://localhost:8080/notification';
topic : string = "/notifications/messages"
constructor(){
console.log("Initialize WebSocket Connection");
let ws = new SockJS(this.webSocketEndPoint);
this.stompClient = Stomp.over(ws);
const _this = this;
_this.stompClient.connect({}, function (frame : any) {
_this.stompClient.subscribe(_this.topic, function (sdkEvent : any) {
_this.onMessageReceived(sdkEvent);
});
},);
}
disconnect() {
if (this.stompClient !== null) {
this.stompClient.disconnect();
}
console.log("Disconnected");
}
onMessageReceived(message : NotificationWebSocket) {
console.log("Message Recieved from Server :: " + message);
}
}
此代码在页面加载时加载的组件中初始化
在spring启动的后端我有以下websocket配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/notification");
config.setApplicationDestinationPrefixes("/wigstat");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/notifications").setAllowedOrigins( "*" ).withSockJS();
}
}
@Controller
public class WebSockerSender {
@Autowired
private NotificationWebSocketAdapter notificationWebSocketAdapter;
@MessageMapping("/updates")
@SendTo("/notifications/messages")
public NotificationWebSocket send(Notification notification) {
return notificationWebSocketAdapter.fromEntityToWebSocket( notification );
}
}
如您所见,这是所有教程都显示的超级简单的配置。
为了正常休息端点的 CORS 目的,我在后端配置中有一个 Cors 过滤器
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
res.setHeader( "Access-Control-Allow-Origin", "*" );
res.setHeader( "Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS" );
res.setHeader( "Access-Control-Allow-Headers", "*" );
// Just REPLY OK if request method is OPTIONS for CORS (pre-flight)
if ( req.getMethod().equals("OPTIONS") ) {
res.setHeader( "Access-Control-Max-Age", "86400" );
res.setStatus( HttpServletResponse.SC_OK );
return;
}
chain.doFilter( request, response );
}
@Override
public void destroy() { }
@Override
public void init(FilterConfig filterConfig) { }
}
当我 运行 前端和我检查控制台日志时,我看到以下内容:
我不明白为什么我无法连接这个超级简单的配置。
用逻辑定义的 Rest enpoints 作为 rest 控制器工作得很好
提前致谢
如果我像这样更改 cors 过滤器或 websocket 配置
res.setHeader( "Access-Control-Allow-Origin", "http://localhost:4200" );
和
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/notifications").setAllowedOrigins( "http://localhost:4200" ).withSockJS();
}
我得到同样的错误
FIX
我把cors过滤器改成了这个,还加了
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
String origin = req.getHeader("Origin");
res.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : "*");
res.setHeader( "Access-Control-Allow-Credentials", "true" );
res.setHeader("Vary", "Origin");
res.setHeader( "Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS" );
res.setHeader( "Access-Control-Allow-Headers", "*" );
// Just REPLY OK if request method is OPTIONS for CORS (pre-flight)
if ( req.getMethod().equals("OPTIONS") ) {
res.setHeader( "Access-Control-Max-Age", "86400" );
res.setStatus( HttpServletResponse.SC_OK );
return;
}
chain.doFilter( request, response );
}
.setAllowedOrigins("http://localhost:4200") 在配置中。现在我必须弄清楚如何为所有不同的环境配置它,而不仅仅是在本地
修复
我将 cors 过滤器更改为此并添加
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
String origin = req.getHeader("Origin");
res.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : "*");
res.setHeader( "Access-Control-Allow-Credentials", "true" );
res.setHeader("Vary", "Origin");
res.setHeader( "Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS" );
res.setHeader( "Access-Control-Allow-Headers", "*" );
// Just REPLY OK if request method is OPTIONS for CORS (pre-flight)
if ( req.getMethod().equals("OPTIONS") ) {
res.setHeader( "Access-Control-Max-Age", "86400" );
res.setStatus( HttpServletResponse.SC_OK );
return;
}
chain.doFilter( request, response );
}
.setAllowedOrigins("http://localhost:4200") 在配置中。现在我必须弄清楚如何为所有不同的环境配置它,而不仅仅是在本地(可能使用 @ConfigurationPropeties 或在字符串数组中添加来自本地主机的所有原始设备)
修复
我将 cors 过滤器更改为这个并添加
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
String origin = req.getHeader("Origin");
res.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : "*");
res.setHeader( "Access-Control-Allow-Credentials", "true" );
res.setHeader("Vary", "Origin");
res.setHeader( "Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS" );
res.setHeader( "Access-Control-Allow-Headers", "*" );
// Just REPLY OK if request method is OPTIONS for CORS (pre-flight)
if ( req.getMethod().equals("OPTIONS") ) {
res.setHeader( "Access-Control-Max-Age", "86400" );
res.setStatus( HttpServletResponse.SC_OK );
return;
}
chain.doFilter( request, response );
}
setAllowedOrigins("http://localhost:4200") 在配置中。现在我必须弄清楚如何为所有不同的环境配置它,而不仅仅是在本地
我正在使用 Spring boot 和 Angular 12 在本地开发一个 websocket。我已经阅读了很多教程,但我遇到了一个奇怪的 Cors 错误。
连接套接字的Angular代码如下:
import { Injectable } from '@angular/core';
import { NotificationWebSocket } from '../model/NotificationWebSocket.model';
import { Stomp } from '@stomp/stompjs';
import * as SockJS from 'sockjs-client';
@Injectable({
providedIn: 'root'
})
export class WebsocketService{
stompClient: any;
webSocketEndPoint: string = 'http://localhost:8080/notification';
topic : string = "/notifications/messages"
constructor(){
console.log("Initialize WebSocket Connection");
let ws = new SockJS(this.webSocketEndPoint);
this.stompClient = Stomp.over(ws);
const _this = this;
_this.stompClient.connect({}, function (frame : any) {
_this.stompClient.subscribe(_this.topic, function (sdkEvent : any) {
_this.onMessageReceived(sdkEvent);
});
},);
}
disconnect() {
if (this.stompClient !== null) {
this.stompClient.disconnect();
}
console.log("Disconnected");
}
onMessageReceived(message : NotificationWebSocket) {
console.log("Message Recieved from Server :: " + message);
}
}
此代码在页面加载时加载的组件中初始化
在spring启动的后端我有以下websocket配置
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/notification");
config.setApplicationDestinationPrefixes("/wigstat");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/notifications").setAllowedOrigins( "*" ).withSockJS();
}
}
@Controller
public class WebSockerSender {
@Autowired
private NotificationWebSocketAdapter notificationWebSocketAdapter;
@MessageMapping("/updates")
@SendTo("/notifications/messages")
public NotificationWebSocket send(Notification notification) {
return notificationWebSocketAdapter.fromEntityToWebSocket( notification );
}
}
如您所见,这是所有教程都显示的超级简单的配置。
为了正常休息端点的 CORS 目的,我在后端配置中有一个 Cors 过滤器
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class CorsFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
res.setHeader( "Access-Control-Allow-Origin", "*" );
res.setHeader( "Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS" );
res.setHeader( "Access-Control-Allow-Headers", "*" );
// Just REPLY OK if request method is OPTIONS for CORS (pre-flight)
if ( req.getMethod().equals("OPTIONS") ) {
res.setHeader( "Access-Control-Max-Age", "86400" );
res.setStatus( HttpServletResponse.SC_OK );
return;
}
chain.doFilter( request, response );
}
@Override
public void destroy() { }
@Override
public void init(FilterConfig filterConfig) { }
}
当我 运行 前端和我检查控制台日志时,我看到以下内容:
我不明白为什么我无法连接这个超级简单的配置。
用逻辑定义的 Rest enpoints 作为 rest 控制器工作得很好
提前致谢
如果我像这样更改 cors 过滤器或 websocket 配置
res.setHeader( "Access-Control-Allow-Origin", "http://localhost:4200" );
和
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/notifications").setAllowedOrigins( "http://localhost:4200" ).withSockJS();
}
我得到同样的错误
FIX
我把cors过滤器改成了这个,还加了
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
String origin = req.getHeader("Origin");
res.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : "*");
res.setHeader( "Access-Control-Allow-Credentials", "true" );
res.setHeader("Vary", "Origin");
res.setHeader( "Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS" );
res.setHeader( "Access-Control-Allow-Headers", "*" );
// Just REPLY OK if request method is OPTIONS for CORS (pre-flight)
if ( req.getMethod().equals("OPTIONS") ) {
res.setHeader( "Access-Control-Max-Age", "86400" );
res.setStatus( HttpServletResponse.SC_OK );
return;
}
chain.doFilter( request, response );
}
.setAllowedOrigins("http://localhost:4200") 在配置中。现在我必须弄清楚如何为所有不同的环境配置它,而不仅仅是在本地
修复
我将 cors 过滤器更改为此并添加
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
String origin = req.getHeader("Origin");
res.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : "*");
res.setHeader( "Access-Control-Allow-Credentials", "true" );
res.setHeader("Vary", "Origin");
res.setHeader( "Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS" );
res.setHeader( "Access-Control-Allow-Headers", "*" );
// Just REPLY OK if request method is OPTIONS for CORS (pre-flight)
if ( req.getMethod().equals("OPTIONS") ) {
res.setHeader( "Access-Control-Max-Age", "86400" );
res.setStatus( HttpServletResponse.SC_OK );
return;
}
chain.doFilter( request, response );
}
.setAllowedOrigins("http://localhost:4200") 在配置中。现在我必须弄清楚如何为所有不同的环境配置它,而不仅仅是在本地(可能使用 @ConfigurationPropeties 或在字符串数组中添加来自本地主机的所有原始设备)
修复
我将 cors 过滤器更改为这个并添加
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletResponse res = (HttpServletResponse) response;
HttpServletRequest req = (HttpServletRequest) request;
String origin = req.getHeader("Origin");
res.setHeader("Access-Control-Allow-Origin", allowedOrigins.contains(origin) ? origin : "*");
res.setHeader( "Access-Control-Allow-Credentials", "true" );
res.setHeader("Vary", "Origin");
res.setHeader( "Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS" );
res.setHeader( "Access-Control-Allow-Headers", "*" );
// Just REPLY OK if request method is OPTIONS for CORS (pre-flight)
if ( req.getMethod().equals("OPTIONS") ) {
res.setHeader( "Access-Control-Max-Age", "86400" );
res.setStatus( HttpServletResponse.SC_OK );
return;
}
chain.doFilter( request, response );
}
setAllowedOrigins("http://localhost:4200") 在配置中。现在我必须弄清楚如何为所有不同的环境配置它,而不仅仅是在本地