В запросе отсутствует заголовок "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 предоставит вам встроенный сервер, который может прокси-запрос. Следующие следующие шаги:
- Добавьте файл proxy.config.json в корневой каталог вашего проекта.
Добавьте следующий код в файл proxy.config.json
{ "/api/": { "target": { "host": "localhost", "protocol": "http:", "port": 8080 }, "secure": false, "changeOrigin": true, "logLevel": "debug" } }
В файле package.json найдите запуск под скриптами и замените его следующим:
ng serve --proxy-config proxy.config.json
Измените свой угловой код с помощью следующего кода:
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
Подробнее о прокси-конфиге: ссылка