Я запускаю службу с использованием Spring, и мой интерфейс Angular получает 403 с методом запроса: OPTIONS, когда он пытается сделать запрос POST.
И служба Spring, и приложение Angular работают на моей машине локально. Я попытался переключить CORS с помощью плагина Chrome, но, похоже, это не помогло.
Все мои запросы GET к службе работают нормально. Я могу выполнить запрос POST в Postman, поэтому я не уверен, почему приложение angular не может сделать запрос, но Postman может.
****РЕДАКТИРОВАТЬ****
Заголовки ответа
Allow: GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH
Content-Length: 20
Date: Sat, 31 Mar 2018 19:15:01 GMT
Заголовки запроса
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Access-Control-Request-Headers: content-type
Access-Control-Request-Method: POST
Connection: keep-alive
Host: localhost:9901
Origin: http://localhost:4200
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.162 Safari/537.36
@RomanC Да, мое приложение angular использует httpClient для выполнения почтового вызова с объектом json.
Но не работает
Ваш интерфейс делает запрос CORS, чтобы узнать, какие методы (HTTP Verbs) разрешены при вашей поддержке. Обычно это требуется для денежных операций, например, POST или PUT, которые предназначены для изменения данных.
Следовательно, ваш Frontend сначала сделает этот вызов, а ваш backend должен ответить разрешенными методами, вы также можете ограничить определенные URI, а затем после успешной проверки будет выполнен целевой вызов.
Это совершенно нормально, и angular делает это внутренне, чтобы не делать ненужных запросов данных, не зная, разрешит ли сервер.
Вот как вы настроите это в Spring.
//Change/Customize as necessary
@Bean
CorsConfigurationSource corsConfigurationSource() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration corsConfiguration = new CorsConfiguration();
corsConfiguration.addAllowedOrigin("<your origin>");
corsConfiguration.setAllowedMethods(Arrays.asList(
HttpMethod.GET.name(),
HttpMethod.HEAD.name(),
HttpMethod.POST.name(),
HttpMethod.PUT.name(),
HttpMethod.DELETE.name()));
corsConfiguration.setMaxAge(1800L);
source.registerCorsConfiguration("/**", corsConfiguration); // you restrict your path here
return source;
}
Если вы также используете какой-либо пользовательский response headers из вашего бэкэнда, вам необходимо разрешить это также в конфигурации CORS.
В качестве примера
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addExposedHeader("header1");
corsConfiguration.addExposedHeader("header2");
Поэтому я добавил это объявление Bean в свой класс приложения чуть ниже основного. Я все еще, кажется, получаю ошибку 403 OPTIONS Invalid CORS request, когда пытаюсь выполнить операцию POST. Есть ли что-нибудь, что мне нужно сделать на стороне Angular?
Какие заголовки вы получаете в запросе параметров? Прочтение об этом может помочь вам в дальнейшем github.com/spring-projects/spring-security-oauth/issues/938
Добавил в пост заголовки из неудавшегося запроса :)
Если вы хотите добавить это к отправленному вами коду ответа, я отмечу это галочкой! :)
В классе corsConfiguration доступны опции maxAge и origins, я добавил эти сеттеры выше.
Чтобы исправить все проблемы CORS в проекте Angular (передняя часть) и Spring boot (бэкэнд), добавьте следующий компонент Spring:
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Component
@Order(Ordered.HIGHEST_PRECEDENCE)
public class ConfigCtrl implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
final HttpServletResponse response = (HttpServletResponse) res;
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Allow-Headers", "Authorization, Content-Type");
response.setHeader("Access-Control-Max-Age", "3600");
if ("OPTIONS".equalsIgnoreCase(((HttpServletRequest) req).getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
} else {
chain.doFilter(req, res);
}
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig config) throws ServletException {
}
}
PS для новичков: имя класса и его расположение в приложении Spring значения не имеют.
Кредит Аджитешу Кумару.
Если мы говорим о SpringBoot, предположительно последней или, по крайней мере, последней версии, то мы можем просто использовать аннотацию @CrossOrigin рядом с аннотацией @RestController в наших классах контроллеров. Доступен с версии Spring ver. 4.2
Например:
@RestController
@CrossOrigin
@RequestMapping("/api")
public class MyObjectsController {
private final MyObjectsService service;
@Autowired
public MyObjectsController(MyObjectsService service) {
this.service = service;
}
@GetMapping("/version")
public Version getVersion() {
return service.getVersion();
}
@PostMapping("/objects")
public ObjectResource createObject(@RequestBody @Valid ObjectData data) {
return service.createObject(data);
}
@GetMapping("/objects/{id}")
public ObjectResource getObject(@PathVariable String id) {
return service.getObjectById(id);
}
}
Преимущества:
Referer)Смотрите также:
почтовый запрос используется с почтовыми данными.