React Native+Node/Express下Axios POST请求网络错误排查
问题排查:React Native Axios拦截器中POST请求网络错误
问题背景
开发的应用前端基于React Native,后端采用Node.js+Express框架,创建了两个Axios实例分别对接主服务器(3000端口)和认证服务器(4000端口)。所有常规服务调用均可正常工作,但主服务器实例的请求拦截器内调用认证服务器的/token接口时,始终触发[AxiosError: Network Error],两个服务均在本地运行。
前端代码
import axios from 'axios'; import AsyncStorage from '@react-native-async-storage/async-storage'; const BASE_URL = 'URL_PLACEHOLDER'; // <- 我的计算机IP地址 export const instanceMain = axios.create({ baseURL: `${BASE_URL}:3000`, timeout: 1000, }); export const instanceAuth = axios.create({ baseURL: `${BASE_URL}:4000`, }); // 拦截请求以检查是否需要刷新令牌 instanceMain.interceptors.request.use(async function (response) { const accessToken = await AsyncStorage.getItem('accessToken'); const refreshToken = await AsyncStorage.getItem('refreshToken'); await instanceAuth .post(`/token`, { accessToken: accessToken, refreshToken: refreshToken, }) .then((res) => { AsyncStorage.setItem('accessToken', res.data.accessToken); AsyncStorage.setItem('refreshToken', res.data.refreshToken); }) .catch((error) => { console.log(error); }); return response; });
后端认证接口代码
app.post('/token', async (req, res) => { try { const accessToken = req.body.accessToken; const refreshToken = req.body.refreshToken; if (accessToken == null || accessToken == undefined) return res.sendStatus(401); // 验证AccessToken jwt.verify(accessToken, process.env.ACCESS_TOKEN_SECRET, (error) => { // 如果令牌过期,应执行此逻辑。我认为可能处理方式有误,但这是我想到的唯一方法。 if (error) { // tokenDB是存储所有有效刷新令牌的本地JSON数据库 tokenDB.read(); tokenDB.data ||= { tokens: [] }; if (refreshToken == null) return res.sendStatus(401); // 检查tokenDB中是否不存在该刷新令牌,若不存在则返回403 if (!tokenDB.data.tokens.includes(refreshToken)) { return res.sendStatus(403); } // 验证RefreshToken jwt.verify( refreshToken, process.env.REFRESH_TOKEN_SECRET, (error, account) => { // 删除account中的iat,否则新令牌将与之前的相同 delete account.iat; if (error) return res.sendStatus(403); // 生成新令牌 const newAccessToken = generateAccessToken(account); const newRefreshToken = generateRefreshToken(account); // 从tokenDB中移除旧的refreshToken并添加新的refreshToken tokenDB.data.tokens = tokenDB.data.tokens.filter( (token) => token !== refreshToken ); tokenDB.data.tokens.push(newRefreshToken); // 返回结果:新的Access和Refresh令牌 res.json({ accessToken: newAccessToken, refreshToken: newRefreshToken, }); tokenDB.write(); } ); } else { return res.sendStatus(100); } }); } catch (error) { console.error(error); } });
错误信息
报错仅显示:[AxiosError: Network Error],error.config内容如下:
{"adapter": [Function xhrAdapter], "baseURL": "IP_PLACEHOLDER:4000", "data": "{\"accessToken\":\"ACCESS_TOKEN_PLACEHOLDER\",\"refreshToken\":\"REFRESH_TOKEN_PLACEHOLDER\"}", "env": {"Blob": [Function Blob], "FormData": [Function FormData]}, "headers": {"Accept": "application/json, text/plain, */*", "Content-Type": "application/json"}, "maxBodyLength": -1, "maxContentLength": -1, "method": "post", "timeout": 0, "transformRequest": [[Function transformRequest]], "transformResponse": [[Function transformResponse]], "transitional": {"clarifyTimeoutError": false, "forcedJSONParsing": true, "silentJSONParsing": true}, "url": "/token", "validateStatus": [Function validateStatus], "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN"}
排查与解决建议
- 修正BASE_URL格式:React Native中Axios的baseURL必须包含协议头(
http://或https://),比如const BASE_URL = 'http://192.168.1.100';,直接写IP会被识别为无效URL,导致网络请求失败。 - 修复拦截器参数错误:请求拦截器的参数是
config而非response,原代码中async function (response)是错误的,应改为async function (config),最后返回config,否则会破坏请求流程。 - 验证认证服务可用性:用Postman或curl直接调用
http://[你的IP]:4000/token,手动传入包含accessToken和refreshToken的JSON body,确认服务能正常响应,排除服务本身的问题。 - 配置CORS中间件:在认证服务器的Express项目中安装并启用cors中间件,避免跨域拦截:
const cors = require('cors'); app.use(cors()); - 检查React Native网络权限:
- Android:确保
AndroidManifest.xml中添加了<uses-permission android:name="android.permission.INTERNET" /> - iOS:若使用本地http服务,需在
Info.plist中添加NSAllowsArbitraryLoads并设为YES,绕过ATS限制
- Android:确保
- 添加超时配置:给instanceAuth实例设置合理的超时时间,比如
timeout: 5000,避免因无超时设置导致的异常。
内容的提问来源于stack exchange,提问作者Nilzh
相关产品推荐
相关产品推荐

