ОПЦИИ Http-запрос завершается с ошибкой 404, в то время как почтовый запрос работает нормально - PullRequest
3 голосов
/ 01 июля 2019

У меня есть конечная точка покоя с необязательной переменной PathVariable в Spring.

@PostMapping("/API_PATH/{param1}/{param2}")
public Result getResult(@PathVariable Integer param1,
    @PathVariable(required = false) Integer param2, @RequestBody Data data) {
    // SOME LOGIC HERE
}

Я отметил param2 Переменная Path как необязательная.Так что это необязательное значение.Этот POST API работает нормально, когда я не отправляю значение param2.Но когда браузер пытается получить доступ к этому API, он отправляет запрос типа OPTIONS перед отправкой фактического запроса POST.Теперь, если запрос OPTIONS не содержит вторую переменную пути (param2) в URL, он завершается с ошибкой 404.Есть ли способ обойти эту проблему?

Ответы [ 2 ]

3 голосов
/ 01 июля 2019

ОПЦИИ Запросы - это то, что мы называем предполетными запросами при совместном использовании ресурсов общего пользования (CORS), который проверяет меры безопасности.Для этого вам может потребоваться добавить конфигурации CORS

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class WebConfig implements Filter,WebMvcConfigurer {

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

    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
      HttpServletResponse response = (HttpServletResponse) res;
      HttpServletRequest request = (HttpServletRequest) req;
      System.out.println("WebConfig; "+request.getRequestURI());
      response.setHeader("Access-Control-Allow-Origin", "*");
      response.setHeader("Access-Control-Allow-Methods", "POST, PUT, GET, OPTIONS, DELETE");
      response.setHeader("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With,observe");
      response.setHeader("Access-Control-Max-Age", "3600");
      response.setHeader("Access-Control-Allow-Credentials", "true");
      response.setHeader("Access-Control-Expose-Headers", "Authorization");
      response.addHeader("Access-Control-Expose-Headers", "responseType");
      response.addHeader("Access-Control-Expose-Headers", "observe");
      System.out.println("Request Method: "+request.getMethod());
      if (!(request.getMethod().equalsIgnoreCase("OPTIONS"))) {
          try {
              chain.doFilter(req, res);
          } catch(Exception e) {
              e.printStackTrace();
          }
      } else {
          System.out.println("Pre-flight");
          response.setHeader("Access-Control-Allow-Origin", "*");
          response.setHeader("Access-Control-Allow-Methods", "POST,GET,DELETE,PUT");
          response.setHeader("Access-Control-Max-Age", "3600");
          response.setHeader("Access-Control-Allow-Headers", "Access-Control-Expose-Headers"+"Authorization, content-type," +
          "USERID"+"ROLE"+
                  "access-control-request-headers,access-control-request-method,accept,origin,authorization,x-requested-with,responseType,observe");
          response.setStatus(HttpServletResponse.SC_OK);
      }

    }

}

Некоторые другие способы настройки CORS с использованием CorsRegistry:

@Override
public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/api/**")
        .allowedOrigins("http://domain1.com","http://domain2.com");
}

Использование @CrossOrigin:

@CrossOrigin(origins = {"http://domain1.com","http://domain2.com"})

Использование application.properties

management.endpoints.web.cors.allowed-origins=http://domain1.com,http://domain2.com
0 голосов
/ 01 июля 2019

Ваш код специально для POST, поэтому для OPTIONS нет обработчика. Spring предоставляет аннотацию CrossOrigin, которая реализует предполётный обработчик CORS, здесь читается здесь .

Попробуйте это:

@CrossOrigin
@PostMapping("/API_PATH/{param1}/{param2}")
public Result getResult(@PathVariable Integer param1,
@PathVariable(required = false) Integer param2, @RequestBody Data data) {
    // SOME LOGIC HERE
}
...