Я уже некоторое время борюсь с этой проблемой. У меня есть промежуточное ПО на моем веб-API .NET Core, которое будет отправлять удобное сообщение об ошибке на основе кода ошибки, возвращаемого моим SQL Server.
Это отлично работает в Postman, и когда я отключаю ту же политику происхождения для Chrome, Отсюда
Так что это довольно веское свидетельство того, что это проблема CORS. После просмотра множества сообщений о проблемах я все еще не смог решить проблему.
ВОПРОС:
Если я добавлю расширение Allow-Control-Allow-Origin в Chrome здесь, все будет работать, как ожидалось. Всем ли пользователям моего приложения потребуется, чтобы это было установлено в их браузерах, чтобы получать правильные ошибки во внешнем интерфейсе? Это моя самая большая проблема. Вот моя конфигурация ниже:
Политика при запуске веб-API
app.UseCors(builder => builder
.AllowAnyOrigin()
.AllowAnyMethod()
.AllowAnyHeader()
.AllowCredentials());
Я зарегистрировал его до MVC
services.AddCors();
services.AddMvc();
Это мой метод в Angular
addNewPeopleCategory(
personCategory: CreatePeopleCategory
): Observable<CreatePeopleCategory> {
return this.http
.post<CreatePeopleCategory>(this.url + "/create", personCategory)
.pipe(catchError(this.handleErrorUpdate.bind(this)));
}
Это мой метод обработки ошибок в Angular
private handleErrorUpdate(errorResponse: HttpErrorResponse) {
if (errorResponse.error instanceof ErrorEvent) {
console.info("Client Side Error: ", errorResponse.error.message);
} else {
console.info("Server Side Error: ", errorResponse);
}
this.openSnackbar(errorResponse.error);
return throwError(
"There is an issue with the service. Please try again later.
);
}
Когда CORS не отключен
Когда CORS отключен в Chrome
Суть в том, что если вы хотите, чтобы код внешнего интерфейса мог отлавливать 400 ошибок и выполнять определенную обработку для них, тогда вам необходимо, чтобы сервер добавил заголовок Access-Control-Allow-Origin в ответы 4xx. Но в любом случае, что касается того, что видят конечные пользователи вашего внешнего приложения, вы все равно не хотите раскрывать им эту ошибку 400 - потому что причина этой ошибки 400 в том, что код вашего внешнего интерфейса отправляет неверный запрос, и нет ничего конечный пользователь вашего приложения может исправить это, поэтому непонятно, в чем будет смысл пытаться раскрыть им какую-либо информацию об этой ошибке.
@sideshowbarker Итак, я не хочу, чтобы пользователь видел 400 неверных запросов. Я хочу, чтобы они видели сообщение об ошибке, созданное сервером. В моем примере выше пользователь пытается создать повторяющуюся категорию. Это перехватывается моим промежуточным программным обеспечением, потому что это ошибка SQL-сервера, в частности, код ошибки SQL: 2601. Код ошибки 2601 - это случай, когда я написал специальное сообщение, которое будет отправлено обратно в качестве ответа на вызов API. Это просто строка, которая отправляется в пользовательский интерфейс Angular и отображается на панели закусок для пользователя. Поскольку я технически отправляю строку ошибки обратно пользователю, не следует ли мне использовать 400?
Если вы используете 400 или любой 4xx - любой другой, кроме 2xx - тогда вам необходимо настроить сервер так, чтобы он включал в ответ Access-Control-Allow-Origin. По умолчанию сервер не добавляет заголовок Access-Control-Allow-Origin в ответы 4xx.
Спасибо за отличное объяснение, я не хотел заставлять вас повторяться в конце, извините! У меня есть способ лучше понять, что происходит сейчас. В моем сообщении выше я думал, что то, что я делаю в startup.cs моего API, должно обрабатывать то, что вы мне говорите. Судя по всем сообщениям, которые я прочитал, он должен добавлять Access-Control-Allow-Origin в каждый мой ответ. Я ошибаюсь? Разве это не подходящее решение?
Да, вы должны добавлять заголовок Access-Control-Allow-Origin в каждый ответ. Но код, показанный в вопросе, не приводит к добавлению его в ответы об ошибках 4xx. Этот код, вероятно, только приводит к добавлению его к 2хх успешным ответам. На большинстве серверов, если вы хотите, чтобы сервер добавлял пользовательские заголовки в ответы об ошибках 4xx, вам необходимо выполнить некоторую специальную конфигурацию в дополнение к любой конфигурации, которую вы обычно делаете для добавления заголовков в ответы. Так что вы, вероятно, захотите изучить документацию сервера и другие вопросы + ответы здесь, в Stack Overflow, чтобы понять, как это сделать.
@sideshowbarker Спасибо за вашу помощь. Я установил свои собственные исключения, чтобы возвращать только 200 ответов, даже если это действительно было 400 или 500, и это все равно давало мне ту же проблему. Это заставило меня поверить, что именно промежуточное ПО удаляло заголовок Access-Control-Allow-Origin. Удаление этой строки решает проблему, context.Response.Clear (); Теперь все работает как положено. Вот ссылка на руководство для всех, ссылка на сайт
Пожалуйста, рассмотрите возможность публикации деталей вашего решения в качестве ответа, чтобы другие пользователи Stack Overflow, столкнувшиеся с той же проблемой в будущем, могли найти ваш ответ, чтобы помочь им решить свою проблему.





Проблема заключалась не в том, как я обрабатывал CORS на сервере, а в промежуточном программном обеспечении, которое я использовал для обработки ошибок.
Я следовал этому руководству здесь, и он работает довольно хорошо. Проблема заключалась в этой строке в самом классе промежуточного программного обеспечения:
context.Response.Clear();
Удаление этой строки сразу устранило мои проблемы с CORS. Кто-то, кто прокомментировал внизу поста, сообщил мне об этом. Из того, что я собираю, эта строка очистит заголовки CORS из ответа, а затем повторно назначит мой указанный код состояния и тип контента.
Вы захотите оставить все остальное в классе без изменений.
Причина, по которой браузер отправляет два запроса, заключается в том, что первый запрос - это предварительный запрос OPTIONS CORS. И код ответа 204, который сервер отправляет обратно для этого, подходит, так что предварительная проверка будет успешной, потому что ответ также включает необходимые заголовки Access-Control-Allow- *. Но POST-запрос из вашего внешнего кода завершается с ошибкой 400 - по-видимому, из-за того, что запрос не соответствует формату, ожидаемому сервером. Но ваш интерфейсный код не может получить доступ к этому ответу, потому что сервер (как и большинство серверов) не добавляет заголовки Access-Control-Allow- * к ошибкам 4xx.