FastAPI WebSocket文档示例运行报403错误:React组件连接问题
问题原因及解决方案
核心问题分析
你遇到403错误的原因有两个:
- WebSocket连接URL不符合FastAPI服务端的路由规则,官方示例的WebSocket端点是
/items/{item_id}/ws,而非你写的/items - 没有携带服务端要求的认证token,官方示例的WebSocket接口需要通过查询参数传递token做身份校验
具体修复步骤
1. 修正WebSocket连接地址
修改connect函数,从输入框读取itemId和token的值,拼接成符合要求的URL:
function connect(event) { const itemId = document.getElementById('itemId').value; const token = document.getElementById('token').value; // 拼接正确的WebSocket URL,包含item_id路径参数和token查询参数 ws = new WebSocket( `ws://localhost:8000/items/${itemId}/ws?token=${token}` ); // 添加错误回调,方便排查后续问题 ws.onerror = function(error) { console.error('WebSocket连接错误:', error); }; ws.onmessage = function(event) { var messages = document.getElementById('messages'); var message = document.createElement('li'); var content = document.createTextNode(event.data); message.appendChild(content); messages.appendChild(message); }; event.preventDefault(); }
2. (可选)改用React状态管理DOM元素
React推荐用状态而非直接操作DOM,你可以把itemId、token、messageText和messages改成组件状态,让代码更符合React规范:
import { useState } from 'react'; const Socket = () => { const [ws, setWs] = useState(null); const [itemId, setItemId] = useState('foo'); const [token, setToken] = useState('some-key-token'); const [messageText, setMessageText] = useState(''); const [messages, setMessages] = useState([]); function connect(event) { const newWs = new WebSocket( `ws://localhost:8000/items/${itemId}/ws?token=${token}` ); newWs.onerror = function(error) { console.error('WebSocket连接错误:', error); }; newWs.onmessage = function(event) { setMessages(prev => [...prev, event.data]); }; setWs(newWs); event.preventDefault(); } function sendMessage(event) { if (ws) { ws.send(messageText); setMessageText(''); } event.preventDefault(); } return ( <div> <h1>WebSocket Chat</h1> <form onSubmit={sendMessage}> <label> Item ID:{' '} <input type='text' value={itemId} onChange={(e) => setItemId(e.target.value)} autoComplete='off' /> </label> <label> Token:{' '} <input type='text' value={token} onChange={(e) => setToken(e.target.value)} autoComplete='off' /> </label> <button type="button" onClick={connect}>Connect</button> <br /><br /> <label> Message: <input type='text' value={messageText} onChange={(e) => setMessageText(e.target.value)} autoComplete='off' /> </label> <button type="submit">Send</button> </form> <ul> {messages.map((msg, index) => ( <li key={index}>{msg}</li> ))} </ul> </div> ); }; export default Socket;
3. 验证服务端配置
确保FastAPI服务端的WebSocket路由确实是/items/{item_id}/ws,并且要求token查询参数做认证,比如官方示例中的核心路由代码:
@app.websocket("/items/{item_id}/ws") async def websocket_endpoint( websocket: WebSocket, item_id: str, token: str = Query(...), ): # 服务端认证及连接处理逻辑
内容的提问来源于stack exchange,提问作者Sarah
相关产品推荐
相关产品推荐

