Vue中使用STOMP连接WebSocket时,为什么总提示连接被拒绝?
我正在用Vue+Stomp.js实现一个聊天功能,按照文档配置了SockJS和STOMP,但连接一直报错”WebSocket connection to ‘ws://localhost:8080/socket’ failed: Error during WebSocket handshake: Unexpected response 404″。已经确认后端Spring Boot的WebSocket配置没问题,本地访问能正常收到消息,但前端就是连不上。
代码是这样写的:
<template>
<div>Chat component</div>
</template>
<script>
import SockJS from 'sockjs-client'
import { Stomp } from '@stomp/stompjs'
export default {
mounted() {
const socket = new SockJS('http://localhost:8080/socket') // 这里是不是写错了?
const stompClient = Stomp.over(socket)
stompClient.connect({}, (frame) => {
console.log('Connected:', frame)
}, (error) => {
console.error('连接失败:', error) // 总会触发这个错误
})
}
}
</script>
我已经试过把SockJS构造函数里的地址改成相对路径’/socket’,但依然不行。浏览器控制台显示连接请求返回了404,但后端日志里完全没有收到请求记录,这会不会是跨域问题?或者STOMP配置哪里漏了?
Spring Boot默认的SockJS endpoint是你在配置类里定义的,比如常见的
registry.addEndpoint("/socket").withSockJS(),那前端就必须连这个路径。你现在写的是http://localhost:8080/socket,看着没错,但得确定后端服务真跑在8080端口,并且这个endpoint名字完全一致。常见坑是开发环境用了Vue CLI的proxy,或者后端实际启在别的端口比如8081、9000。建议你在浏览器直接访问
http://localhost:8080/socket/info看有没有返回json数据(SockJS握手需要这个接口)。如果没有,就是服务没起来或路径错了。另外,虽然你用了SockJS客户端,但地址别写完整URL,通用的做法是用相对路径避免跨域干扰。比如改成
new SockJS('/socket'),前提是你的Vue开发服务器代理了这个路径,或者前后端同源。如果前端跑在3000端口,直接连8080就属于跨域,虽然WebSocket本身支持跨域,但得后端显式允许。检查Spring配置有没有加
setAllowedOrigins("*")或类似设置。最后试试在代码里加上调试:
看看具体握手过程卡在哪一步。十有八九是路径不对或者服务没起来。先确保能手动访问
/socket/info返回数据,再连STOMP。