#reactjs #api #react-hooks
Вопрос:
Здравствуйте, у меня возникли проблемы с обновлением моего изображения. В «Почтальоне» я получаю ошибку cors. У меня есть способ обновить фотографию профиля пользователя, но когда я пытаюсь загрузить ее, это выдает ошибку cors. Попробовал поискать, но все равно не получилось.
API отлично работает в Postman.
Это мой API, который я получаю из бэкэнда
И я получаю доступ к нему через
const updatePhoto = (userId, token, user) => {
return fetch(`${API}/user/photo/${userId}`, {
method: "POST",
headers: {
Accept: "application/json",
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
},
body: JSON.stringify(user),
})
.then((response) => {
return response.json()
})
.catch((err) => {
//console.log(err)
})
}
Это страница, которую я использую, когда пытаюсь обновить фотографию
const UserDetailsPage = () => {
const classes = useStyles()
const [userData, setUserData] = useState({
_id: "",
name: "",
phone: "",
address: "",
birthdate: "",
gender: "",
messenger: "",
photo: "",
email: "",
})
const [open, setOpen] = useState(false)
const [openPicture, setOpenPicture] = useState(false)
const [loaded, setLoaded] = useState(false)
const { height, width } = useWindowDimensions()
const [picture, setPicture] = useState(null)
const [imgData, setImgData] = useState(null)
const [isRedirected, setIsRedirected] = useState(false)
const [imageLink, setImageLink] = useState("")
const {
_id,
name,
phone,
address,
photo,
gender,
messenger,
birthdate,
email,
} = userData
const isMountedRef = React.useRef(false)
useEffect(() => {
isMountedRef.current = true
return () => (isMountedRef.current = false)
}, [])
useEffect(() => {
const user = getUser()
// console.log(userData)
getUserById("/user/" user.userId, user.token)
.then((data) => {
if (isMountedRef.current) {
setUserData(data)
setLoaded(true)
}
})
.catch((error) => {
console.log(error)
})
}, [])
const handleOpen = () => {
setOpen(true)
}
const handleClose = () => {
setOpen(false)
}
const handleOpenPicture = () => {
setOpenPicture(true)
}
const handleClosePicture = () => {
setOpenPicture(false)
}
const handleChangePicture = (name) => (e) => {
setUserData({ ...userData, [name]: e.target.value })
}
const onChangePicture = (e) => {
e.preventDefault()
if (e.target.files[0]) {
// console.log("picture: ", e.target.files)
setPicture(e.target.files[0])
const reader = new FileReader()
reader.addEventListener("load", () => {
setImgData(reader.result)
})
reader.readAsDataURL(e.target.files[0])
setImageLink(e.target.files[0].name)
}
}
const clickSubmitPicture = (e) => {
const users = getUser()
console.log("imageLink", imageLink)
e.preventDefault()
console.log(userData)
updatePicture(_id, users.token, imageLink).then((data) => {
if (data) {
Swal({
text: "Your Photo has been updated",
icon: SparkWaving,
}).then(() => {
setIsRedirected(true)
})
} else {
Swal({
title: "Photo updated failed.",
text: "The server encountered an error.",
icon: "error",
})
}
})
}
if (isRedirected) {
navigate("/user")
}
return (
<MuiThemeProvider theme={theme}>
<AppBar elevation={0}>
<Toolbar>
<Link to="/food">
<ArrowBackIcon className={classes.backSize} />
</Link>
</Toolbar>
</AppBar>
<Toolbar />
<div>
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
open={open}
onClose={handleClose}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade in={open}>
<div>
<img
src={photo}
alt="User Profile"
className={`${classes.centerFit}`}
/>
</div>
</Fade>
</Modal>
</div>
{loaded ? (
<>
<div className={classes.center}>
<label htmlFor="upload-photo">
<div>
<Modal
aria-labelledby="transition-modal-title"
aria-describedby="transition-modal-description"
open={openPicture}
onClose={handleClosePicture}
closeAfterTransition
BackdropComponent={Backdrop}
BackdropProps={{
timeout: 500,
}}
>
<Fade
in={openPicture}
style={{
backgroundColor: "white",
}}
>
<Box className={classes.modal}>
<input
type="file"
style={{ paddingTop: "20px" }}
onChange={onChangePicture}
/>
<div style={{ paddingTop: "1.5em" }}></div>
<div style={{ textAlign: "center" }}>
<img
src={imgData}
style={{
width: "100%",
height: "200px",
alignItems: "center",
}}
/>
</div>
<div style={{ paddingTop: "100px" }}></div>
<Button
type="submit"
fullWidth
variant="contained"
className={classes.button}
style={{ fontFamily: "visby" }}
onClick={clickSubmitPicture}
>
Upload
</Button>
</Box>
</Fade>
</Modal>
</div>
<CameraAltIcon
onClick={handleOpenPicture}
className={` ${classes.camera} ${classes.float} `}
/>
</label>
<button
onClick={handleOpen}
style={{ border: "0", backgroundColor: "transparent" }}
>
<Avatar className={classes.avatar}>
{photo ? (
<img
src={photo}
className={`${classes.large} ${classes.center} ${classes.img}`}
onChange={handleChangePicture("photo")}
/>
) : (
name.charAt(0)
)}
</Avatar>
</button>
</div>
</>
) : (
<div
style={{
display: "flex",
height: height,
justifyContent: "center",
alignItems: "center",
}}
>
<CircularProgress color="secondary" />
</div>
)}
</MuiThemeProvider>
)
}
export default UserDetailsPage
Это сообщение об ошибке
Я что-то упускаю при получении своего API?
Комментарии:
1. Вы тестировали этот API с помощью postman, curl, insomnia или чего-то подобного?
2. здравствуйте, с почтальоном все нормально работает.
3. версия flutter также работает нормально. но в моей реакции, потому что я мигрирую. возникла проблема с cors.
Ответ №1:
Добавьте это промежуточное программное обеспечение cors — NPM в свой внутренний API, а также прочитайте о CORS в MDN, чтобы вы поняли, что
Ответ №2:
Как указано в сообщении об ошибке, вам необходимо указать правильный заголовок в запрошенном источнике, чтобы внести свой источник в белый список.
Access-Control-Allow-Origin: <your origin>
Обходной путь состоит в том, чтобы обеспечить
Access-Control-Allow-Origin: *
в котором перечислены все источники, однако это, вероятно, не лучшая практика / рекомендуется.
Комментарии:
1. Привет, у меня есть бэкэнд
res.header("Access-Control-Allow-Origin", "*");
, я все еще получаю ошибку с проблемой cors.2. Хм, ты заглядывал в промежуточное программное обеспечение cors? section.io/engineering-education/… Возможно, придется включить и другие методы, но я не совсем уверен.
3. Да, я перепробовал много подходов. мой интерфейс просто неправильный?