Сервер не добавляет заголовок ответа Access-Control-Allow-Origin в ответ об ошибке 400

Я уже некоторое время борюсь с этой проблемой. У меня есть промежуточное ПО на моем веб-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 не отключен

Сервер не добавляет заголовок ответа Access-Control-Allow-Origin в ответ об ошибке 400

Когда CORS отключен в Chrome

Сервер не добавляет заголовок ответа Access-Control-Allow-Origin в ответ об ошибке 400

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

sideshowbarker 08.12.2018 23:51

Суть в том, что если вы хотите, чтобы код внешнего интерфейса мог отлавливать 400 ошибок и выполнять определенную обработку для них, тогда вам необходимо, чтобы сервер добавил заголовок Access-Control-Allow-Origin в ответы 4xx. Но в любом случае, что касается того, что видят конечные пользователи вашего внешнего приложения, вы все равно не хотите раскрывать им эту ошибку 400 - потому что причина этой ошибки 400 в том, что код вашего внешнего интерфейса отправляет неверный запрос, и нет ничего конечный пользователь вашего приложения может исправить это, поэтому непонятно, в чем будет смысл пытаться раскрыть им какую-либо информацию об этой ошибке.

sideshowbarker 08.12.2018 23:59

@sideshowbarker Итак, я не хочу, чтобы пользователь видел 400 неверных запросов. Я хочу, чтобы они видели сообщение об ошибке, созданное сервером. В моем примере выше пользователь пытается создать повторяющуюся категорию. Это перехватывается моим промежуточным программным обеспечением, потому что это ошибка SQL-сервера, в частности, код ошибки SQL: 2601. Код ошибки 2601 - это случай, когда я написал специальное сообщение, которое будет отправлено обратно в качестве ответа на вызов API. Это просто строка, которая отправляется в пользовательский интерфейс Angular и отображается на панели закусок для пользователя. Поскольку я технически отправляю строку ошибки обратно пользователю, не следует ли мне использовать 400?

CAlex 09.12.2018 00:13

Если вы используете 400 или любой 4xx - любой другой, кроме 2xx - тогда вам необходимо настроить сервер так, чтобы он включал в ответ Access-Control-Allow-Origin. По умолчанию сервер не добавляет заголовок Access-Control-Allow-Origin в ответы 4xx.

sideshowbarker 09.12.2018 00:30

Спасибо за отличное объяснение, я не хотел заставлять вас повторяться в конце, извините! У меня есть способ лучше понять, что происходит сейчас. В моем сообщении выше я думал, что то, что я делаю в startup.cs моего API, должно обрабатывать то, что вы мне говорите. Судя по всем сообщениям, которые я прочитал, он должен добавлять Access-Control-Allow-Origin в каждый мой ответ. Я ошибаюсь? Разве это не подходящее решение?

CAlex 09.12.2018 01:51

Да, вы должны добавлять заголовок Access-Control-Allow-Origin в каждый ответ. Но код, показанный в вопросе, не приводит к добавлению его в ответы об ошибках 4xx. Этот код, вероятно, только приводит к добавлению его к 2хх успешным ответам. На большинстве серверов, если вы хотите, чтобы сервер добавлял пользовательские заголовки в ответы об ошибках 4xx, вам необходимо выполнить некоторую специальную конфигурацию в дополнение к любой конфигурации, которую вы обычно делаете для добавления заголовков в ответы. Так что вы, вероятно, захотите изучить документацию сервера и другие вопросы + ответы здесь, в Stack Overflow, чтобы понять, как это сделать.

sideshowbarker 09.12.2018 02:11

@sideshowbarker Спасибо за вашу помощь. Я установил свои собственные исключения, чтобы возвращать только 200 ответов, даже если это действительно было 400 или 500, и это все равно давало мне ту же проблему. Это заставило меня поверить, что именно промежуточное ПО удаляло заголовок Access-Control-Allow-Origin. Удаление этой строки решает проблему, context.Response.Clear (); Теперь все работает как положено. Вот ссылка на руководство для всех, ссылка на сайт

CAlex 09.12.2018 03:08

Пожалуйста, рассмотрите возможность публикации деталей вашего решения в качестве ответа, чтобы другие пользователи Stack Overflow, столкнувшиеся с той же проблемой в будущем, могли найти ваш ответ, чтобы помочь им решить свою проблему.

sideshowbarker 09.12.2018 03:47
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
0
8
188
1

Ответы 1

Проблема заключалась не в том, как я обрабатывал CORS на сервере, а в промежуточном программном обеспечении, которое я использовал для обработки ошибок.

Я следовал этому руководству здесь, и он работает довольно хорошо. Проблема заключалась в этой строке в самом классе промежуточного программного обеспечения:

context.Response.Clear();

Удаление этой строки сразу устранило мои проблемы с CORS. Кто-то, кто прокомментировал внизу поста, сообщил мне об этом. Из того, что я собираю, эта строка очистит заголовки CORS из ответа, а затем повторно назначит мой указанный код состояния и тип контента.

Вы захотите оставить все остальное в классе без изменений.

Другие вопросы по теме