В запросе отсутствует заголовок "Access-Control-Allow-Origin"

Я прочитал много тем об этом, и это все еще не работает, я схожу с ума.

У меня есть приложение Angular6 с Spring Api, и я продолжаю иметь эту ошибку, когда я вызываю его:

Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

И все же я чувствую, что сделал все:

Вот мой вызов API в Angular App:

getGamesFromServer() {
  const httpOptions = {
    headers: new HttpHeaders({
      'Access-Control-Allow-Origin':'*'
    })
  };

  this.httpClient
    .get<any[]>('http://localhost:8080/api/rest/v1/game/progress', httpOptions)
    .subscribe(
      (response) => {
        console.log(response);
        this.games = response;
        console.log(this.games);
        this.emitGameSubject();
      },
      (error) => {
        console.log('Erreur ! : ' + error);
      }
    );
}

Вот метод Java называется:

@RequestMapping(method = GET, value = "/progress")
@ResponseBody
public Response findAllAndProgress() {
    return Response.status(Response.Status.OK)
            .entity(gameService.findAllAndProgress())
            .header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
            .build();
}

Я также запустил Chrome с активированной опцией --disable-web-security, а также скачал расширение Chrome, чтобы разрешить запрос CORS, но это было бесполезно.

3 ответа

Решение

Я предполагаю, что это потому, что приложение Angular работает в режиме разработки и обслуживается из другого порта, чем веб-приложение Spring. Вы можете решить это с proxy.conf.json файл, который вы указываете при запуске приложения (ng serve --proxy-config proxy.conf.json) или как быстрое и грязное (но менее готовое к производству) решение, которое вы можете добавить @CrossOrigin(origins = "*") к вашим Spring контроллерам.

Причина того, что следующий код не работает:

@RequestMapping(method = GET, value = "/progress")
@ResponseBody
public Response findAllAndProgress() {
    return Response.status(Response.Status.OK)
        .entity(gameService.findAllAndProgress())
        .header(ACCESS_CONTROL_ALLOW_ORIGIN, "*")
        .build();
}

потому что этот метод никогда не выполняется, чтобы добавить заголовок. Запросы между источниками инициируют предварительный запрос (HTTP OPTION) перед отправкой фактического запроса (HTTP GET в вашем случае). Это тот предполетный запрос, который терпит неудачу. Вот почему добавление аннотации к контроллеру решит проблему.

На Java добавить следующую строку на вашем API

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

Вы также можете прокси свой запрос от угловой стороны. Angular предоставит вам встроенный сервер, который может прокси-запрос. Следующие следующие шаги:

  1. Добавьте файл proxy.config.json в корневой каталог вашего проекта.
  2. Добавьте следующий код в файл proxy.config.json

    { "/api/": { "target": { "host": "localhost", "protocol": "http:", "port": 8080 }, "secure": false, "changeOrigin": true, "logLevel": "debug" } }

  3. В файле package.json найдите запуск под скриптами и замените его следующим:

    ng serve --proxy-config proxy.config.json

  4. Измените свой угловой код с помощью следующего кода:

    this.httpClient.get ('/ api / rest / v1 / game / progress', httpOptions).subscribe ((response) => {console.log (response); this.games = response; console.log (this.games); this.emitGameSubject ();}, (error) => {console.log ('Erreur!:' + error);});

Создайте файл proxy.conf.json в корневом каталоге со следующим содержимым:

{ 
  "/api/*": {
    "target": "http://localhost:8080",
    "secure": false
  }
}

И в файле package.json вы должны изменить стартовый скрипт с ng serve в ng serve --proxy-config proxy.conf.json

Подробнее о прокси-конфиге: ссылка

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