React发送POST请求执行登出时出现AxiosError 401错误(Postman可正常运行)
浏览器控制台返回错误:
Logout error: AxiosError {message: 'Request failed with status code 401', name: 'AxiosError', code: 'ERR_BAD_REQUEST'
前端初始登出代码
axios.post('http://*****azure public domain*****/api/accounts/logout', {}, { withCredentials: true }) .then(response => { console.log('Logout successful'); }) .catch(error => { console.error('Logout failed:', error); });
后端CORS与Session配置(server.js)
const cors = require('cors'); app.use(cors({ origin: (origin, callback) => { callback(null, true); }, methods: ["POST", "GET", "PUT", "DELETE"], credentials: true })); app.use(session({ key: 'session_cookie_name', secret: 'secret', store: sessionStore, resave: false, saveUninitialized: false, cookie: { secure: false, maxAge: 1000 * 60 * 60 * 24 } }));
登出控制器代码
exports.logout = async (req, res) => { if (req.session.username) { req.session.destroy(err => { if (err) { return res.status(500).json({ message: 'Error during logout' }); } res.clearCookie('session_cookie_name'); return res.status(200).json({ message: 'Logged out successfully' }); }); } else { return res.status(401).json({ message: 'Already logged out' }); } };
尝试过的axios.create封装代码
import axios from 'axios'; const apiClient = axios.create({ baseURL: 'http://******azure public domain******/api', withCredentials: true, headers: { 'Content-Type': 'application/json' }, timeout: 5000 }); export default apiClient; export const logout = () => async (dispatch) => { try { const response = await apiClient.post('/accounts/logout'); dispatch({ type: 'LOGOUT' }); } catch (err) { console.log('Logout error:', err); } };
排查方向
Session Cookie未在浏览器中携带:虽然配置了
withCredentials: true,但要确认浏览器是否真的把session cookie发送给了后端。可以在浏览器开发者工具的Network面板中查看登出请求的Cookie头,确认session_cookie_name是否存在。Postman能正常运行是因为它会自动保存并携带Cookie,而浏览器有同源策略限制,即使CORS允许,也要确保Cookie的SameSite属性配置正确(当前代码没设置,默认是Lax,在跨域POST请求中可能不会携带)。Cookie的Secure属性问题:后端配置
secure: false,但如果你的前端是HTTPS协议,浏览器会拒绝发送非Secure的Cookie。如果Azure部署的后端是HTTPS,需要把secure: true,同时设置sameSite: 'None'(跨域场景下),否则浏览器不会携带Cookie。Session验证逻辑:后端登出接口判断
req.session.username是否存在,若不存在返回401。要确认前端发起登出请求时,后端是否真的能读取到有效的session。可以在后端接口中打印req.session,看是否有username字段,排查session存储(sessionStore)是否正常工作,比如Redis或其他存储是否配置正确。CORS origin配置:当前CORS设置
origin: (origin, callback) => callback(null, true)允许所有源,但某些浏览器在跨域携带Cookie时,要求origin不能是通配符(虽然这里是动态允许,但可能存在兼容性问题)。可以尝试把origin设置为前端的具体域名,比如origin: 'https://your-frontend-domain.com',再测试是否正常。请求预检问题:跨域POST请求会先发送OPTIONS预检请求,要确保后端正确处理OPTIONS请求,CORS配置中的methods已经包含OPTIONS(当前配置的methods里没有,需要加上
"OPTIONS"),否则预检失败会导致实际请求无法发送,间接出现401。
内容的提问来源于stack exchange,提问作者JisuEun

