React请求未走Node.js代理端口5000,如何解决?
问题描述
我正在开发一个Node.js+React.js应用,用concurrently管理进程,已在React配置中设置代理:
"proxy":"http://localhost:5000/"
API运行在5000端口,React运行在3000端口。注册新用户时出现错误:
Cannot POST api/users
控制台显示请求地址为http://localhost:3000/api/users,但预期应为http://localhost:5000/api/users。以下是我的Register.js和users.js代码,请问问题出在哪?该如何解决?
Register.js 代码
import React, { Fragment, useState } from 'react' import axios from 'axios'; const Register = () => { const [formData, setFormData] = useState({ name:'', email: '', password: '', password2: '' }); const { name, email, password, password2 } = formData; const onChange = e => setFormData({ ...formData, [e.target.name]:e.target.value }); const onSubmit = async e => { e.preventDefault(); if(password !== password2){ console.log('Passwords do not match') } else { const newUser = { name, email, password } try { const config = { headers:{ 'Content-type': 'application/json' } } const body = JSON.stringify(newUser) const res = await axios.post('api/users', body, config); console.log(res.data); } catch (error) { console.error(error.response.data) } } } return ( <Fragment> <section className='container'> <h1 className="large text-primary">Sign Up</h1> <p className="lead"><i className="fas fa-user"></i> Create Your Account</p> <form className="form" action="create-profile.html" onSubmit={e => onSubmit(e)}> <div className="form-group"> <input type="text" placeholder="Name" name="name" value={name} onChange={e => onChange(e)} required /> </div> <div className="form-group"> <input type="email" placeholder="Email Address" name="email" value={email} onChange={e => onChange(e)} required/> <small className="form-text" >This site uses Gravatar so if you want a profile image, use a Gravatar email</small > </div> <div className="form-group"> <input type="password" placeholder="Password" name="password" minLength="6" value={password} onChange={e => onChange(e)} required /> </div> <div className="form-group"> <input type="password" placeholder="Confirm Password" name="password2" minLength="6" value={password2} onChange={e => onChange(e)} required /> </div> <input type="submit" className="btn btn-primary" value="Register" /> </form> <p className="my-1"> Already have an account? <a href="login.html">Sign In</a> </p> </section> </Fragment> ) } export default Register
users.js 代码
//@route POST api/users //@desc Register user //@access public router.post('/', [ check('name', 'Name is required') .not() .isEmpty(), check('email', 'Plese include a valid email').isEmail(), check('password', 'Please enter a password with 6 or more characters').isLength({min:6}) ], async (req, res)=> { const errors = validationResult(req); if(!errors.isEmpty()){ return res.status(400).json({ errors:errors.array()}); //400 is for bad requests } const { name, email, password } = req.body; try{ //See if user exists let user = await User.findOne({ email }); if(user){ return res.status(400).json({ errors: [{ msg:'User already exists' }] }); } //Get users gravatar const avatar = gravatar.url(email,{ s:'200', r:'pg', d:'mm' }) user = new User({ name, email, avatar, password }); //Encrypt password const salt = await bcrypt.genSalt(10); user.password = await bcrypt.hash(password, salt); await user.save(); //Return jsonwebtoken -> this for users to be logged in right after registration const payload = { user:{ id: user.id } } jwt.sign( payload, config.get('jwtSecret'), {expiresIn: 360000}, //change to 3600 for production (err, token)=>{ if(err) throw err; res.json({ token }); } ) }catch(err){ console.error('err.message'); res.status(500).send('Server Error'); } }); module.exports = router;
问题分析与解决方案
核心问题
请求路径缺少开头的斜杠,导致React代理无法识别并转发请求。当你写'api/users'时,浏览器会将其解析为当前域名下的相对路径,即http://localhost:3000/api/users;只有路径以/开头('/api/users'),React代理才会将请求转发到代理目标http://localhost:5000/api/users。
另外还有两个小问题:
- axios默认会自动序列化JSON对象并设置
Content-Type,不需要手动调用JSON.stringify和设置headers - users.js中有两处小错误:
Plese拼写错误、console.error('err.message')会打印字符串而非错误信息
修复步骤
- 修改Register.js中的axios请求路径,添加开头的斜杠,同时简化请求代码:
// 替换原来的请求代码 const res = await axios.post('/api/users', newUser);
如果一定要手动设置headers,也可以保留config,但必须加斜杠:
const config = { headers:{ 'Content-type': 'application/json' } } const res = await axios.post('/api/users', newUser, config);
- 修复users.js中的两处错误:
// 将Plese改为Please check('email', 'Please include a valid email').isEmail(), // 将'err.message'改为err.message console.error(err.message);
修改完成后,请求会被React代理正确转发到5000端口的API,匹配到users.js中的路由逻辑。
内容的提问来源于stack exchange,提问作者tukitooo1998
相关产品推荐
相关产品推荐

