Angular 7 Заголовок «Access-Control-Allow-Origin» содержит несколько значений

Я обслуживал угловое приложение через порт 4202 и подключался к приложению remove spring mvc с помощью приведенного ниже кода.

this.http.post<Hero[]>('http://localhost:8080/api/hero/list', {"id":1}, httpOptions)

Но он сообщил об ошибке ниже.

Failed to load http://localhost:8080/api/hero/list: 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:4202' is therefore not allowed access. The response had HTTP status code 403.

Поэтому я попытался включить cors в своем весеннем веб-приложении с помощью аннотации ниже в методе контроллера.

@CrossOrigin(origins = "http://localhost:4202")

Я также попытался добавить класс конфигурации, как показано ниже.

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**");
    }
}

Затем я обновляю интерфейс интерфейса, как сказано ниже.

Failed to load http://localhost:8080/api/hero/list: The 'Access-Control-Allow-Origin' header contains multiple values 'http://localhost:4202, *', but only one is allowed. Origin 'http://localhost:4202' is therefore not allowed access.

Затем я проверил свою сеть Chrome, как показано ниже, она действительно дублировала заголовок «Access-control-allow-origin». введите описание изображения здесь

Затем я много гуглил, нашел, что другие ребята столкнулись с этой проблемой, так как другой веб-сервер перед tomcat генерирует вторую голову «Access-control-allow-origin». Но у меня есть только один сервер tomcat, за исключением сервера, запущенного с помощью «ng serve».

Затем я попытался посетить этот URL (http://localhost:8080/api/hero/list ) непосредственно скрипачом вместо углового. И ниже скриншот, я могу обнаружить, что нет дублированного «Access-Control-Allow-Origin». введите описание изображения здесь

Итак, я догадался, было ли это вызвано сервером nodejs, запущенным angular? Поскольку я был новичком в angular, я не знаю, как разобраться в этой проблеме. Спасибо.


person liam xu    schedule 01.11.2018    source источник
comment
Поскольку вы делаете вызов с помощью localhost:8080/api... внутри вашего Angular HttpClient, не проходите мимо локального сервера разработки Angular CLI. Вы переходите прямо к конечной точке Spring. Так что это должно быть каким-то образом проблема на стороне сервера. В качестве примечания: я обычно не делаю запросы CORS, а использую конфигурацию прокси на моем сервере разработки Angular CLI, чтобы избежать необходимости выполнять CORS на бэкэнде. У меня есть статья о том, как это настроить: juristr.com/blog/2016/11/configure-proxy-api-angular-cli   -  person Juri    schedule 01.11.2018


Ответы (3)


Angular работает не так, как ваш сервер приложений Java, поэтому требуется CORS. Я не эксперт Spring, но, насколько я понимаю, ваша проблема происходит следующим образом: когда вы выполняете запрос POST, сервер сам добавляет заголовок разрешения источника. Он может прочитать спецификацию метода Endpoints, чтобы добавить требуемый заголовок разрешенных методов (по крайней мере, в Java EE) и установить заголовок allow origin * (что я настоятельно не рекомендую для производства, лучше установите ожидаемые разрешенные домены). Из-за аннотации вашего контроллера устанавливается дополнительный заголовок. Это недопустимо, так как спецификация CORS. Убедитесь, что установлен только один, настроив сервер приложений так, чтобы он не устанавливался, и обработайте это с помощью какой-либо аннотации или позвольте серверу приложений обработать это или установить этот заголовок с помощью балансировщика нагрузки (если вы его используете). Второе (фактически первоначальная ошибка, которую вы получили) — это предварительный запрос. Если вы делаете запрос, который может изменить состояние сервера (например, почтовый запрос), cors требует, чтобы вы сначала ответили на запрос OPTIONS (чтобы браузер мог проверить cors перед отправкой запроса на изменение). Этот запрос параметров должен иметь код ответа 200ish и предоставлять заголовки cors allow для происхождения и методов (включая публикацию в вашем случае).

Для локальной разработки вы также можете использовать прокси, например этот. Это не заставляет вас иметь дело с cors локально и модифицировать ваш бэкэнд.

person HC42    schedule 26.10.2019

Вы добавляете два заголовка в свой серверный код, просто удалите @CrossOrigin(origins = http://localhost:4202) и сохраните конфигурацию WebConfig только потому, что вы разрешаете все источники в этой конфигурации.

person pranit patil    schedule 23.04.2021

У меня тоже такая же проблема. В моем случае мой внутренний сервер был основан на архитектуре микросервиса (spring webflux), и все микросервисы обновляли заголовок перекрестного происхождения, из-за чего он имел несколько значений, затем я исправил это, переместив конфигурацию cors только на шлюз, удалив его из все остальные микросервисы. Это решило мою проблему!

person Ravi Soni    schedule 30.07.2021