如何从Node.js服务端向客户端返回数据?回调接口获取rdata失败求解
存在的问题
- 客户端请求路径与服务端路由不匹配:服务端暴露的接口路径为
/callback,但客户端请求地址为http://localhost:5000/callback:id,多余的:id后缀会导致服务端无法匹配到对应路由,不会执行返回逻辑。 - 客户端请求缺少必填参数:服务端路由逻辑判断仅当
req.query.code存在时才会执行后续SSO接口调用逻辑,直接发起的GET请求未携带code、state参数,会直接跳过所有处理流程,没有任何返回结果。 - 服务端返回JSON格式错误:通过
JSON.parse(body2)得到的rdata是JS对象,而res.end()仅支持传入字符串或Buffer类型参数,直接传JS对象会抛出错误,无法正常返回数据;另外设置的Content-Type: text/json不符合标准,标准JSON类型应为application/json。 - 异常分支无兜底返回:当前服务端代码仅在有
code参数的分支有返回逻辑,无code、接口调用失败的场景没有明确返回,会导致请求超时挂起。 - 不符合OAuth2授权流程逻辑:OAuth2授权码模式需要先引导用户跳转到SSO授权页,用户授权后SSO会自动重定向到配置的
/callback地址,并自动带上code和state参数,不能直接主动调用/callback接口获取数据。
修复方案
客户端修改
先获取SSO重定向带回的code参数后再发起请求,同时修正请求路径:
useEffect(() => { // 从当前页面URL中提取SSO回调携带的code、state参数 const urlParams = new URLSearchParams(window.location.search) const code = urlParams.get('code') const state = urlParams.get('state') // 没有code说明还未完成SSO授权,不发起请求 if (!code) return const apiCall = async () => { try { // 路径和服务端对齐,去掉多余的:id,传入code、state参数 const response = await axios.get(`http://localhost:5000/callback`, { params: { code, state } }) console.log('获取到的rdata:', response.data) } catch (err) { console.error('请求失败:', err) } }; apiCall(); }, []);
服务端修改
补全兜底逻辑、修正JSON返回方式:
app.get("/callback", cors(), (req, res) => { const { code, state } = req.query // 无code参数时直接返回错误 if (!code) { return res.status(400).json({ error: '缺少授权必填参数code' }) } var token_url = "https://www.ssoservice.kr/oauth2.0/token"; var options = { url: token_url, method: "POST", form: { grant_type: "authorization_code", client_id: client_id, client_secret: client_secret, redirect_uri: redirectURI, code: code, state: state, }, }; request(options, function (error1, response1, body1) { if (!error1 && response1.statusCode == 200) { var tdata = JSON.parse(body1); var options2 = { url: "https://www.ssoservice/oauth2.0/resource", headers: { "Content-Type": "application/json", Authorization: "Bearer " + tdata.access_token, }, }; request(options2, function (error2, response2, body2) { if (!error2 && response2.statusCode == 200) { var rdata = JSON.parse(body2); // 直接用express内置的json方法,自动设置Content-Type并转JSON字符串 res.json(rdata); console.log(rdata); } else { res.status(response2?.statusCode || 500).json({ error: '获取用户资源失败' }); console.log("error2 = " + response2?.statusCode); } }); } else { res.status(response1?.statusCode || 500).json({ error: '获取access_token失败' }); console.log("error1 = " + response1?.statusCode); } }); });
额外检查项
确认你在SSO平台申请应用时填写的redirect_uri和代码中redirectURI变量值完全一致,不一致会导致获取access_token失败。
内容的提问来源于stack exchange,提问作者Somi
相关产品推荐
相关产品推荐

