使用Axios调用第三方API:终端成功React集成失败问题排查
问题描述
需搭建本地内部服务器与第三方外部服务器的通信桥接,测试登录功能时出现以下差异:
- 终端独立运行Axios调用第三方API登录成功
- 集成到React项目后调用第三方API失败
- 调用本地内部服务器的登录功能正常
1. 终端独立运行代码及结果
const axios = require('axios') const Con = async () => { try { console.log('No Error here') const response = await axios .post('https://xyz/pcs/api/account/auth', { "userID": "me", "password": "123" } ) console.log('You are connected to System') console.log('status : ' + response.status) console.log('token : ' + response.data.token); } catch (error) { console.log('Failed to connect') } } Con()
运行结果:
No Error here You are connected to System status : 200 token : xyz123
2. React集成代码及结果
import Button from 'react-bootstrap/Button' import React from 'react' const axios = require('axios') function Connect() { const handleClick = async (e) => { e.preventDefault(); try { const response = await axios .post('https://xyz/pcs/api/account/auth', { "userID": "me", "password": "123" }) console.log('You are connected to System') console.log('status : ' + response.status) console.log('token : ' + response.data.token); } catch (error) {console.log('Failed to connect') } }; return ( <Button variant='info' onClick={handleClick} className='text-white'> Connect to system </Button> ) } export default Connect
运行结果:Failed to connect
3. 本地内部服务器登录代码及结果
import React, { useRef, useState } from 'react' import axios from 'axios' import { useNavigate } from 'react-router-dom'; import { Container, Form, Button } from 'react-bootstrap' const today = new Date() function Login() { const idRef = useRef() const [values, setValues] = useState({ user_name: "", password: "", showPass: false, }); const [ message, setMessage ] = useState('') const navigate = useNavigate(); const Auth = async (e) => { e.preventDefault(); try { await axios .post('http://localhost:3500/login', { user_name: values.user_name, password: values.password }) navigate('/dashboard') } catch (error) { if (error.response) { setMessage(error.response.data.message) console.log(error.response.data.message) return navigate('/') } } }; return ( <Container className="align-items-center d-flex border-none position-absolute top-0 end-0 bg-rose-600 text-white" style={{ height: '100vh', width : '300px' }}> <Form onSubmit={Auth} className="w-100"> <Form.Group> <p className="text-white text-xs italic text-center">{message}</p><br/><hr/><br/> <Form.Label>User Name</Form.Label> <Form.Control type="text" ref={idRef} required placeholder='User name' onChange={(e) => setValues({ ...values, user_name: e.target.value })} /> <p className="text-white text-xs italic">Fill in a user name</p> <Form.Label className='mt-4'> Password</Form.Label> <Form.Control type="password" ref={idRef} required placeholder='Password' onChange={(e) => setValues({ ...values, password: e.target.value })} /> <p className="text-white text-xs italic">Fill in a password</p> </Form.Group> <br/><hr/> <Button type="submit" className="mt-4 border-white bg-rose-700 w-2/3 mx-auto">Login</Button> <p className="text-center text-white text-xs pb-6 mt-2"> © <span>2023 - {today.getFullYear()} </span> Me Corp. All rights reserved. </p> </Form> </Container> ) } export default Login
运行结果:成功获取access和refresh token
问题原因及解决方案
核心原因:浏览器同源策略限制
终端环境无浏览器的同源策略约束,可直接跨域调用第三方API;而React项目运行在本地开发服务器(通常为http://localhost:3000),与第三方API域名https://xyz不同源,浏览器会拦截跨域请求,导致调用失败。
可行解决方案
方案1:配置React开发服务器代理
在React项目的package.json中添加代理配置,将第三方API请求转发到本地服务器,规避跨域:
{ "name": "your-react-app", "proxy": "https://xyz" }
修改React中的请求地址:
// 原地址 .post('https://xyz/pcs/api/account/auth', ...) // 修改后 .post('/pcs/api/account/auth', ...)
重启React开发服务器后,请求会自动转发到第三方API。
方案2:用本地内部服务器做中转桥接
利用已有的本地内部服务器(http://localhost:3500)作为中转,创建接口接收React请求后,再调用第三方API并返回结果。
示例Node.js中转接口(基于Express):
const express = require('express'); const axios = require('axios'); const app = express(); app.use(express.json()); app.post('/proxy-auth', async (req, res) => { try { const response = await axios.post('https://xyz/pcs/api/account/auth', req.body); res.status(response.status).json(response.data); } catch (error) { res.status(error.response?.status || 500).json(error.response?.data || { message: '请求失败' }); } }); app.listen(3500, () => { console.log('本地服务器运行在3500端口'); });
修改React中的请求地址为本地中转接口:
.post('http://localhost:3500/proxy-auth', { "userID": "me", "password": "123" })
方案3:第三方API配置CORS规则
联系第三方合作方,在其API服务器上配置CORS规则,允许你的React开发域名(http://localhost:3000)或生产环境域名发起跨域请求。
内容的提问来源于stack exchange,提问作者615
相关产品推荐
相关产品推荐

