Я занимаюсь разработкой приложения MERN и использую прокси-функцию create-Reaction-app для отправки запросов на мой Express сервер. Я добавил флаг прокси в свой клиентский пакет. Файл json как таковой
"name": "mern",
"version": "0.1.0",
"private": true,
"dependencies": {
ALL DEPENDENCIES REMOVED FOR BREVITY
},
"scripts": {
"start": "react-scripts start",
"dev": "(cd backend && nodemon server) & npm run start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"proxy": "http://localhost:5000",
Я также использую относительные пути в своем приложении React. Все работало прекрасно, но однажды я начал получать 404 ошибки из приложения React, а также ошибки в терминале, говорящие о неправильном запросе. Я не изменил никаких настроек прокси. Прокси-сервер работает с Postman, и я могу получать данные из моего API, но с React / Ax ios он непрерывно возвращает 404 Bad Request, ERR EMPTY RESPONSE или ERRCONREFUSED.
РЕДАКТИРОВАНИЕ: Ax ios Создание экземпляра и маршруты API
import React, { useState, useEffect } from 'react'
import axios from 'axios'
import { Redirect, Link } from 'react-router-dom'
import useForm from '../Helpers/CustomHooks'
import Logo from '../imgs/logo-zephyr.png'
import auth from '../Helpers/AuthService'
import validate from '../Helpers/ValidationRules'
if (auth.loggedIn()) {
axios.defaults.headers.common['authorization'] = auth.getToken()
}
if (!auth.isValid(auth.getToken())) {
auth.setToken(null)
}
const Login = props => {
const { user, setUser } = props
const [tel, setTel] = useState(null)
const [valid, setValid] = useState(false)
const [code, setCode] = useState('')
const [loginForm, setLoginForm] = useState(null)
const [isComplete, setIsComplete] = useState(false)
const [error, setError] = useState(null)
const [authorized, setAuthorized] = useState(null)
const [send, setSend] = useState(false)
const [validverify, setValidverify] = useState(false)
const isEmpty = obj => {
if (obj) {
return Object.keys(obj).length === 0
} else {
return null
}
}
const form = document.getElementById('login')
const verify = (e, code) => {
setError(null)
e.preventDefault()
axios.defaults.headers.common['authorization'] = auth.getToken()
axios
.post('/api/verifycheck', {
tel: tel,
code: code,
token: auth.getToken(),
})
.then(res => {
console.log(res)
if (typeof res.data === 'string' || res.data.err) {
setError(res.data.err)
}
auth.setToken(res.data.token)
const profile = auth.getProfile()
setUser(profile.user)
setAuthorized(profile.authorized)
setValid(true)
setTel(null)
setSend(false)
})
.catch(err => {
console.log(err)
setError(err.response.data)
})
}
const diffLog = () => {
console.log(form)
if (form) {
form.reset()
}
auth.setToken(null)
setTel(null)
}
const handleVerify = e => {
e.persist()
setCode(e.target.value)
if (e.target.value.length === 6) {
setValidverify(true)
}
}
const verifyPrompt = tel => {
setError(null)
axios
.get('/api/verify', {
params: {
tel: tel,
},
})
.then(res => {
//too many requests, throw error saying wait specified period of time
setValid(res.data.valid)
})
.catch(err => {
console.log(err)
err.response && setError(err.response.data)
err.response && console.log(err.response.data)
})
}
const initialValues = {
password1: '',
username: '',
}
const login = async () => {
try {
const data = await auth.login(inputs.username, inputs.password1)
auth.setToken(data.token)
if (auth.loggedIn()) {
try {
const profile = auth.getProfile()
setUser(profile.user)
setAuthorized(profile.authorized)
setTel(profile.user.phoneNumber)
setSend(true)
} catch (err) {
auth.logout()
}
} else {
console.log('not logged in')
}
} catch (err) {
err.response && console.log(err.response.data.err)
setError(err.response.data.err)
}
}
const {
validationErrors,
inputs,
handleInputChange,
handleSubmit,
handleBlur,
handleClick,
} = useForm(login, initialValues, validate)
useEffect(() => {
setLoginForm(form)
}, [form])
useEffect(() => {
if (tel && send) {
verifyPrompt(tel)
}
}, [tel, send])
useEffect(() => {
if (authorized) setValid(authorized)
}, [authorized])
useEffect(() => {
if (auth.loggedIn()) {
try {
const profile = auth.getProfile()
setAuthorized(profile.authorized)
setUser(profile.user)
setTel(profile.user.phoneNumber)
} catch (err) {
auth.logout()
}
}
}, [setUser])
useEffect(() => {
let values = Object.values(inputs)
console.log(values)
let areAnyValsEmpty = values.some(element => element.length === 0)
console.log(
isEmpty(validationErrors),
isComplete,
areAnyValsEmpty,
error
)
if (isEmpty(validationErrors) && !areAnyValsEmpty) {
setIsComplete(true)
}
}, [error, inputs, validationErrors])
if (auth.loggedIn() && user && valid) {
return <Redirect to={`/${user._id}/profile`} />
}
return (
<div className="container-fluid">
<div className="row">
<div className="col-3 img-pane">
<img className="img-fluid" src={Logo} alt="logo.png" />
</div>
<div className="col-lg-6 col-sm-12 registration">
<h3>Login</h3>
{!tel && (
<form id="login" onSubmit={() => login()}>
<div className="form-group">
<input
className={`form-control zephyr-input ${validationErrors &&
validationErrors.username &&
'input-danger'}`}
required
onChange={handleInputChange}
onBlur={handleBlur}
value={inputs.username}
type="text"
name="username"
id="username"
placeholder="Enter username or email"
/>
{validationErrors && (
<p className="text-danger">
{validationErrors.username}
</p>
)}
</div>
<div className="form-group">
<input
className={`form-control zephyr-input ${validationErrors &&
validationErrors.password1 &&
'input-danger'}`}
required
onChange={handleInputChange}
onBlur={handleBlur}
value={inputs.password1}
type="password"
name="password1"
id="password1"
placeholder="Enter password"
/>
{validationErrors && (
<p className="text-danger">
{validationErrors.password1}
</p>
)}
</div>
<button
disabled={error || !isComplete}
onClick={handleSubmit}
className="btn btn-success btn-block mb-3 form-button"
type="button"
>
Login
</button>
<SignUpLink />
</form>
)}
{tel && !authorized && !valid && (
<form onSubmit={e => verify(e, code)}>
<div className="form-group">
<input
className="form-control zephyr-input"
onChange={handleVerify}
value={code || ''}
type="code"
name="code"
id="code"
placeholder="Enter 6-digit verification code"
/>
</div>
<button
disabled={!validverify}
className="btn btn-success btn-block form-button"
type="submit"
>
Verify
</button>
<button
onClick={() => verifyPrompt(tel)}
className="btn btn-warning btn-block form-button"
type="button"
>
Resend Code
</button>
<Link onClick={() => diffLog()} to="/login">
Login with a Different Account
</Link>
</form>
)}
{error && <div className="alert alert-danger">{error}</div>}
</div>
</div>
</div>
)
}
export default Login