Фронтенд: 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)
Обновлено: Это может быть на грани суетливости, но я специально пытаюсь решить эту проблему, изменив код на стороне клиента, а не используя расширения или какие-либо модификации, связанные с браузером. Однако, если это невозможно, я готов изменить код на стороне сервера.
В таком случае, как мне указать, что отправляемые данные - это JSON? Кроме того, в Postman я включил заголовок, указывающий тип содержимого как application / json (при выборе необработанных данных в качестве типа тела), и он по-прежнему работает
в любом случае лучше принять заголовок в своем внутреннем коде, это всего лишь одна строка кода. Вы не можете избежать наказания, если не позаботитесь о CORE.
@RequestMapping(value = "/addevent",method=RequestMethod.POST,produces=org.springframework.http.MediaType.APPLICATION_JSON_VALUE) public ResponseEntity<?> addNewEvent( @RequestBody EventDTO event,HttpServletRequest request) Это подпись моего текущего метода кода на стороне сервера. Как Postman все еще может успешно получить к нему доступ и передать данные JSON на сервер?
«Однако, если это невозможно, я готов изменить код на стороне сервера». - Вам необходимо изменить код на стороне сервера. Было бы глупо, если бы ваша клиентская сторона могла отключить функцию безопасности, предназначенную для предотвращения доступа вашего кода на стороне клиента к другим сайтам.
Хорошо. Как я могу принимать запросы опций на стороне клиента? (Учитывая, что вы говорите, что предоставленного ответа недостаточно)





Эта проблема известна как CORS. Cross Оrigin рesource Sharing. Это возникает, когда источник запроса и ответа различается. Например: если ваш проект находится на https://139.43.33.122:1111/, а ваш сервер размещен на https://123.0.3.444:3000, то источник вашего запроса и ответа совершенно разные, и, таким образом, браузер заблокирует ответ. Это браузер. Почтальону плевать на их происхождение. Чтобы получить ответ, есть 2 способа (может быть и больше, но я использую только эти 2).
Дополнительные заголовки: Если у вас есть доступ / разрешение на код сервера, добавьте дополнительный заголовок к ответам сервера: Контроль доступа-Allow-Origin: http://siteA.com, Access-Control-Allow-Methods: GET, POST, PUT, Access-Control-Allow-Headers: Content-Type.
Используйте расширения: Есть несколько расширений, которые могут обойти это ограничение. ЕСЛИ у вас нет доступа или разрешения на изменение ответа сервера, то это выход. Я лично использую только этот метод.
"Access-Control-Allow-Origin: *" - это предварительный запрос. Этого недостаточно.
«Использовать расширения» - это хитрость для использования во время разработки и совершенно непрактичная во время производства.
Спасибо. Ранее я пробовал использовать расширение CORS для Chrome, но, похоже, это не имело значения. После установки и включения расширения ничего не поделаешь, верно (из того, что я видел, его единственная функция, казалось, включала и выключала)?
@Quentin Согласился на продление. Я должен был упомянуть это в своем вопросе
@Quentin Спасибо, что напомнили, я чуть не забыл про контроль доступа, и да, расширение - это хак для разработчиков.
@RahulSaha, это расширение, которое я использую: chrome.google.com/webstore/detail/allow-control-allow-or igi /…. Иногда вам может потребоваться переключить его 2-3 раза, чтобы сработало, но помните, как сказал Квентин: это всего лишь хакерство от разработчиков. Это нормально, только если ваш проект и сервер будут размещены в одном и том же источнике. Если нет, то не используйте его. Это не решит вашу проблему, поскольку каждому пользователю необходимо установить это расширение в своей системе.
У меня была такая же проблема, и я нашел способ избежать ошибок CORS и 403 благодаря этому статья.
Добавьте Postman Interceptor в свой Google Chrome: https://chrome.google.com/webstore/detail/postman-interceptor/aicmkgpgakddgnaphhhpliifpcfhicfo/support?hl=en
Активировать почтальон-перехватчик в Postman
Откройте инструмент разработки Chrome, перейдите в консоль и вручную добавьте файл cookie, найденный благодаря перехватчику почтальона.
document.cookie = "keyofcookie = valueofcookie"
Повторите запрос, все работает!
В противном случае, просто чтобы избежать CORS, вы можете использовать прокси, описанный здесь.
Спасибо, но разве это не исправление браузера, которое каждый пользователь должен будет делать индивидуально?
К сожалению, ты прав. Это действительно грязное решение. Однако вы можете настроить файл cookie, сделать его вневременным [developer.mozilla.org/fr/docs/Web/API/Document/cookie] и нажимать его в начале каждого сеанса пользователя. Это единственное решение, которое я нашел.
LOL, вам нужно сказать всем своим пользователям установить перехватчик в их браузер LOLOLOOLOLOLOLOL
если вы не передадите заголовки, вы не получите вызов OPTIONS