#javascript #reactjs #http #express #fetch
#javascript #reactjs #http #выразить #выборка
Вопрос:
У меня есть компонент react, и я выполняю сетевой вызов для настройки состояния. В конечном итоге я хочу передать это другим дочерним компонентам, но на данный момент я просто заставляю систему работать.
Я пытаюсь правильно перехватывать ошибки при вызове моей серверной части (экспресс-сервер в приложении). Я попытался принудительно вызвать ошибку, извлекая данные из конечной точки, которая не существует. Это должно выдавать значение 404, поскольку оно не существует, верно? Как я могу заставить эту ошибку появиться в операторе catch? Прямо сейчас моя ошибка SyntaxError: Unexpected token < in JSON at position 0 at eval (app.js:61)
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
data: null
};
}
componentDidMount() {
fetch('/api/wrong_endpoint').then((data) => {
return data.json();
}).then((body) => {
this.setState({data: body})
}).catch(err => console.log(err));
}
render() {
console.log('logging the states');
console.log(this.state.data);
return (
<div>
<ContactList />
<ContactDetail />
<AddContactModal />
</div>
);
}
}
Комментарии:
1. Взгляните на документы wretch . Это библиотека-оболочка для
fetch()
, которая ответит на ваш вопрос и, возможно, вам может быть интересно использовать ее для обработки ошибок. 404 не перейдет вfetch()
catch, если вы не проверите статус (перед возвратомdata.json()
и выдачей собственной ошибки2. Вы пытаетесь распечатать код состояния ошибки / сообщение или что-то в этом роде?
3. @charlietfl ок. Достаточно ли стандартно проверять статус подобным образом и печатать ошибку? Здесь я выполняю сетевой вызов, не так ли? В конечном итоге этот код будет перемещен из компонента в некоторый файл, специфичный для связи с сервером.
4. @wentjun да, это то, что я пытаюсь сделать.
5. ДА… вам нужно создать свою собственную шаблонную передачу ошибок при использовании
fetch()
. Я предпочитаю, чтобы библиотека делала это за меня. Также упрощает публикацию данных
Ответ №1:
Я попытаюсь перейти шаг за шагом
-
fetch
метод не выдает ошибку, даже если вы получаете коды ответа 4xx или 5xx. Пожалуйста, прочтите оFetch API
внимательно, я полагаю, вы можете найти много интересного, чего вы не знаете об этом. -
Вы можете легко проверить статус ответа следующим образом (пожалуйста, прочитайте об
Response
объекте и его методах / свойствах):
fetch('/api/wrong_endpoint').then((response) => {
console.log('status code', response.status)
})
-
Трудно сказать, действительно ли ваш сервер возвращает код 404, потому что я не знаю вашей экспресс-настройки. Если вы установите какой-нибудь запасной обработчик, подобный
app.get('*', ...)
, то он также может вернуть код успеха 200. Вы можете проверить статус ответа и его тело в DevTools браузера. Но я считаю, что будет лучше, если вы настроите хотя бы свой/api
маршрутизатор на возврат ошибки 404, если запрошенный/api/...
маршрут не найден. -
В чем я действительно уверен, так это в том, что ваш сервер возвращает некоторый HTML-макет в ответе. И вы пытаетесь проанализировать ее как строку JSON через
data.json()
и, конечно, получаете синтаксическую ошибку, поскольку это не JSON (html-макет начинается с<
символа, отсюда и ошибка:SyntaxError: Unexpected token <
)
Комментарии:
1. Приятный подробный ответ
Ответ №2:
Как правило, если вы используете fetch API, ошибки 40x и 50x не будут попадать в последующие блоки, поскольку обещание от fetch отклоняет только сетевые ошибки (не ошибки HTTP или что-либо еще). Следовательно, запрос данных с «неправильной» конечной точки будет обработан в первом then
блоке.
Я бы рекомендовал вам использовать check your http response body на основе Response.Ok
свойства. Успешные ответы будут обработаны в рамках этого условия, тогда как любые другие ответы (ok: false) будут обработаны в другом операторе.
fetch('/api/wrong_endpoint')
.then(response => {
console.log(response) // full response body
console.log(response.status); // get only the response.status
if (!response.ok) {
// http errors 40x and 50x will go into this statement
// do something to handle it
} else if (response.ok) {
// handles status code 200
}
})
.then(
// ...