Я работаю над внешним приложением в React, которое подключается к службе промежуточного программного обеспечения, написанной на Spring boot. Я пытаюсь вызвать конечную точку из внешнего интерфейса следующим образом:

return axios.post('http://localhost:8085/workshop/client/createClient', {username})
.then((response) => {
  console.log('Success')
})
.catch((error) => console.log(error));

Всякий раз, когда я делаю запрос в своем браузере, я получаю следующие ошибки:

OPTIONS http://localhost:8085/workshop/client/createClient 401 ()

Failed to load http://localhost:8085/workshop/client/createClient: Response for preflight has invalid HTTP status code 401.

Насколько я понимаю, это потому, что мой запрос промежуточного программного обеспечения блокирует предполётный запрос. Прочитав немного онлайн о включении этого, я добавил CorsFilter в мое приложение весенней загрузки:

@Slf4j
public class CORSFilter implements Filter {
  private static final String ONE_HOUR = "3600";

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
  }

  @Override
  public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
    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-Max-Age", ONE_HOUR);
    response.setHeader("Access-Control-Allow-Headers", "X-Requested-With,Origin,Content-Type, Accept, x-device-user-agent, Content-Type");

    if (req instanceof HttpServletRequest) {
       HttpServletRequest httpServletRequest = (HttpServletRequest) req;
       if (httpServletRequest.getHeader(HttpHeaders.ORIGIN) != null
          && httpServletRequest.getMethod().equals(HttpMethod.OPTIONS.name())
          && httpServletRequest.getHeader(HttpHeaders.ACCESS_CONTROL_REQUEST_METHOD) != null) {
          log.debug("Received an OPTIONS pre-flight request.");
          return;
       }
    }
    chain.doFilter(req, res);
  }

  @Override
  public void destroy() {
  }
}

А также

@Configuration
public class MvcConfiguration {

 @Bean
 public FilterRegistrationBean corsFilter() {
   FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
   filterRegistrationBean.setFilter(new CORSFilter());
   filterRegistrationBean.addUrlPatterns("/*");
   filterRegistrationBean.setOrder(0);
   return filterRegistrationBean;
 }
}

Вот пример конечной точки:

 @PostMapping("/createClient")
 public ResponseEntity<?> createClient(@RequestBody CreateClientDto clientDto) {
    try {
     ...
     return new ResponseEntity<>(responseBody, OK);
    } catch (Exception e ...) {}
  }

Любая помощь была бы весьма признательна :)

Обновление: URL-адрес был немного неверным для запроса (отсюда 404). Я обновил сообщение об ошибке. У меня все еще есть проблемы с CORS.

Это заголовки ответа, которые я вижу в инструментах разработчика:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:access-control-allow-credentials, access-control-allow-methods, access-control-allow-origin, allow, content-type
Access-Control-Allow-Methods:POST
Access-Control-Allow-Origin:http://localhost:3000
Allow:GET, HEAD, POST, PUT, DELETE, TRACE, OPTIONS, PATCH
Cache-Control:no-cache, no-store, max-age=0, must-revalidate
Content-Length:0
Date:Thu, 01 Mar 2018 14:06:38 GMT
Expires:0
Pragma:no-cache
Strict-Transport-Security:max-age=31536000 ; includeSubDomains
Vary:Origin
WWW-Authenticate:Basic realm="Spring"
X-Content-Type-Options:nosniff
X-Frame-Options:DENY
X-XSS-Protection:1; mode=block

И заголовки запроса:

OPTIONS /workshop/client/createClient HTTP/1.1
Host: localhost:8085
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_3) 
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.186 Safari/537.36
Access-Control-Request-Headers: access-control-allow-credentials,access-control-allow-methods,access-control-allow-origin,allow,content-type
Accept: */*
Accept-Encoding: gzip, deflate, br
Accept-Language: en-GB,en;q=0.9,en-US;q=0.8,da;q=0.7
8
liamw9 1 Мар 2018 в 15:00

4 ответа

Лучший ответ

Кажется, проблема решена. Мне не хватало заголовка запроса Accept (спасибо @Anadi Sharma), и в качестве зависимости у меня также была spring-boot-starter-security, которая, похоже, возвращалась неавторизованной. Мне также не понадобился CorsFilter, в конце я просто использовал аннотацию @CrossOrigin на конечной точке.

2
liamw9 1 Мар 2018 в 15:21

У меня также была эта проблема, но позвольте мне дать прямой ответ в более простой форме общения.

Прежде всего, вы должны сообщить своему серверу (Spring boot java) о клиенте (Reactjs) URL .

Например, в большинстве случаев при весенней загрузке используются http://localhost:8080 и Reactjs uses http://localhost:3000.

Таким образом, вам нужно перейти к контроллеру в Spring boot java и разрешить URL Reactjs получить разрешение на доступ к серверу (Spring boot). Это поможет вам избавиться от проблемы CORS .

Как мы это делаем в Spring boot? просто добавляем аннотацию @CrossOrigin, указывающую ссылку URL на Reactjs, как показано ниже:

Например:

 @GetMapping("/orphans")
    @CrossOrigin(origins = "http://localhost:3000")
    Iterable<Student> read() {
        return studentService.findAll();
    }

Вышеуказанный метод состоит в том, чтобы перечислить всех сирот, поэтому я дал Reactjs ссылку URL , а затем избавился от проблемы CORS .

Удачного кодирования.

1
Lutaaya Huzaifah Idris 13 Янв 2019 в 06:09

Controller.java

Обратитесь к приведенному ниже образцу кода для решения этой проблемы.

@CrossOrigin(origins = "http://localhost:3000")
@RequestMapping(value="/sample", method = RequestMethod.GET, produces = "application/json")

public Student getStudent(){
}
0
Suraj Rao 25 Апр 2019 в 08:09

Это стандартная проблема CORS, это в основном означает, что пользовательский агент, т. Е. http://localhost:3000 не имеет разрешений на доступ к ресурсам в http://localhost:8085. Вы можете узнать больше об этом на https://developer.mozilla.org / EN -US / Docs / Web / HTTP / CORS.

Заголовки вашего запроса должны точно соответствовать правилам сервера. Сохранение любого параметра как * не будет работать.

Например, если заголовок вашего запроса имеет следующее:

Access-Control-Request-Method: POST
Access-Control-Request-Headers: <your custom headers>

Затем правила сервера показывают карту вашего заголовка запроса:

Access-Control-Request-Method: GET, PUT, DELETE, POST
Access-Control-Request-Headers: <your custom headers>

Дайте мне знать, если это поможет!

1
Anadi Sharma 1 Мар 2018 в 12:18