Запрос POST не работает из кода Angular5, но работает из Postman

Фронтенд: Angular5

Бэкэнд: Java (работает на сервере Wildfly 8.x)

При отправке HTTP-запроса POST с помощью content-type: 'application/json' из моего приложения Angular на сервер я получаю следующую ошибку:

Failed to load http://localhost:8080/myk/api/v1/events/addevent: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:4200' is therefore not allowed access. The response had HTTP status code 403.

Это код запроса:

const httpOptions = { headers: new HttpHeaders({ 'Content-Type': 'application/json' }) }; this.http.post("http://localhost:8080/myk/api/v1/events/addevent", jsonPayload, httpOptions).subscribe();

При осмотре обнаружил, что вместо запроса POST делался запрос OPTIONS (как в соответствии с эта статья MDN о CORS и предварительных запросах).

Однако, когда я попытался выполнить тот же запрос с помощью Postman, он сработал отлично.

Как почтальон не сталкивается с проблемой с запросом OPTIONS, когда я не обрабатываю запрос OPTIONS на сервере?

Кроме того, что я могу сделать (сохраняя тот же content-type и не изменяя код на стороне сервера), чтобы решить эту проблему?

Примечание 1: Хотя этот вопрос решает ту же проблему, предлагаемое решение требует изменения типа содержимого.

Заметка 2: Когда я запускаю другое приложение (разработанное не мной в Angularjs), которое пытается выполнить запрос POST с использованием вызова ajax, оно работает нормально. (Я не понимаю, почему это работает, и, кроме того, был бы признателен ответ, связанный с angular5. Я включил это примечание на случай, если оно поможет выяснить проблему с приложением Angular5)

Обновлено: Это может быть на грани суетливости, но я специально пытаюсь решить эту проблему, изменив код на стороне клиента, а не используя расширения или какие-либо модификации, связанные с браузером. Однако, если это невозможно, я готов изменить код на стороне сервера.

если вы не передадите заголовки, вы не получите вызов OPTIONS

Milad 19.03.2018 11:52

В таком случае, как мне указать, что отправляемые данные - это JSON? Кроме того, в Postman я включил заголовок, указывающий тип содержимого как application / json (при выборе необработанных данных в качестве типа тела), и он по-прежнему работает

rahs 19.03.2018 12:00

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

Milad 19.03.2018 12:12
@RequestMapping(value = "/addevent",method=RequestMethod.POST,‌​produces=org.springf‌​ramework.http.MediaT‌​ype.APPLICATION_JSON‌​_VALUE) public ResponseEntity<?> addNewEvent( @RequestBody EventDTO event,HttpServletRequest request) Это подпись моего текущего метода кода на стороне сервера. Как Postman все еще может успешно получить к нему доступ и передать данные JSON на сервер?
rahs 19.03.2018 12:17

«Однако, если это невозможно, я готов изменить код на стороне сервера». - Вам необходимо изменить код на стороне сервера. Было бы глупо, если бы ваша клиентская сторона могла отключить функцию безопасности, предназначенную для предотвращения доступа вашего кода на стороне клиента к другим сайтам.

Quentin 19.03.2018 12:37

Хорошо. Как я могу принимать запросы опций на стороне клиента? (Учитывая, что вы говорите, что предоставленного ответа недостаточно)

rahs 19.03.2018 14:15
Тестирование функциональных 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
1
6
6 434
2

Ответы 2

Эта проблема известна как CORS. Cross Оrigin рesource Sharing. Это возникает, когда источник запроса и ответа различается. Например: если ваш проект находится на https://139.43.33.122:1111/, а ваш сервер размещен на https://123.0.3.444:3000, то источник вашего запроса и ответа совершенно разные, и, таким образом, браузер заблокирует ответ. Это браузер. Почтальону плевать на их происхождение. Чтобы получить ответ, есть 2 способа (может быть и больше, но я использую только эти 2).

  1. Дополнительные заголовки: Если у вас есть доступ / разрешение на код сервера, добавьте дополнительный заголовок к ответам сервера: Контроль доступа-Allow-Origin: http://siteA.com, Access-Control-Allow-Methods: GET, POST, PUT, Access-Control-Allow-Headers: Content-Type.

  2. Используйте расширения: Есть несколько расширений, которые могут обойти это ограничение. ЕСЛИ у вас нет доступа или разрешения на изменение ответа сервера, то это выход. Я лично использую только этот метод.

"Access-Control-Allow-Origin: *" - это предварительный запрос. Этого недостаточно.

Quentin 19.03.2018 12:28

«Использовать расширения» - это хитрость для использования во время разработки и совершенно непрактичная во время производства.

Quentin 19.03.2018 12:28

Спасибо. Ранее я пробовал использовать расширение CORS для Chrome, но, похоже, это не имело значения. После установки и включения расширения ничего не поделаешь, верно (из того, что я видел, его единственная функция, казалось, включала и выключала)?

rahs 19.03.2018 12:31

@Quentin Согласился на продление. Я должен был упомянуть это в своем вопросе

rahs 19.03.2018 12:32

@Quentin Спасибо, что напомнили, я чуть не забыл про контроль доступа, и да, расширение - это хак для разработчиков.

Shadab Faiz 19.03.2018 12:37

@RahulSaha, это расширение, которое я использую: chrome.google.com/webstore/detail/allow-control-allow-or‌ igi /…. Иногда вам может потребоваться переключить его 2-3 раза, чтобы сработало, но помните, как сказал Квентин: это всего лишь хакерство от разработчиков. Это нормально, только если ваш проект и сервер будут размещены в одном и том же источнике. Если нет, то не используйте его. Это не решит вашу проблему, поскольку каждому пользователю необходимо установить это расширение в своей системе.

Shadab Faiz 19.03.2018 12:41

У меня была такая же проблема, и я нашел способ избежать ошибок CORS и 403 благодаря этому статья.

  1. Добавьте Postman Interceptor в свой Google Chrome: https://chrome.google.com/webstore/detail/postman-interceptor/aicmkgpgakddgnaphhhpliifpcfhicfo/support?hl=en

  2. Активировать почтальон-перехватчик в Postman

  1. Запустите свой запрос и захватите cookie благодаря интерфейсу Postman

  1. Откройте инструмент разработки Chrome, перейдите в консоль и вручную добавьте файл cookie, найденный благодаря перехватчику почтальона.

    document.cookie = "keyofcookie = valueofcookie"

Повторите запрос, все работает!

В противном случае, просто чтобы избежать CORS, вы можете использовать прокси, описанный здесь.

Спасибо, но разве это не исправление браузера, которое каждый пользователь должен будет делать индивидуально?

rahs 22.03.2018 15:36

К сожалению, ты прав. Это действительно грязное решение. Однако вы можете настроить файл cookie, сделать его вневременным [developer.mozilla.org/fr/docs/Web/API/Document/cookie] и нажимать его в начале каждого сеанса пользователя. Это единственное решение, которое я нашел.

orion_nemo 22.03.2018 15:48

LOL, вам нужно сказать всем своим пользователям установить перехватчик в их браузер LOLOLOOLOLOLOLOL

Jhourlad Estrella 18.06.2019 14:54

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