java - 选项 Http 请求失败并出现 404 异常,而 Post 请求工作正常

标签 java spring-boot rest spring-mvc http-options-method

我在 spring 框架中有一个带有可选 PathVariable 的 rest 端点。

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

我已将 param2 路径变量标记为不需要。所以它是一个可选值。当我不向 param2 发送任何值时,此 POST API 工作正常。但是,当浏览器尝试访问此 API 时,它会在发送实际的 POST 请求之前发送 OPTIONS 类型的请求。现在,如果 OPTIONS 请求不包含 URL 中的第二个路径变量 (param2),它将失败并出现 404 异常。有没有办法解决这个问题?

最佳答案

OPTIONS 请求是我们在跨源资源共享 (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

关于java - 选项 Http 请求失败并出现 404 异常,而 Post 请求工作正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56835272/

相关文章:

java - 如何将 MySQL 数据库的结果加载到网站

c# - 只使用 HttpClient 围绕 RESTful API 构建 MVC 应用程序是否明智?

java - 当 fragment 处于​​恢复状态时,如果条件为真,它将返回到创建 View

java - 错误 : exception in thread 'main' java. lang.ArrayIndexOutOfBoundsException: 0

java - 如何使 Autowired 在 Configuration 类中工作?

javascript - Form Preventdefault 不起作用,重定向到发布 url

java - Ubuntu告诉我找不到spring boot应用程序的init.d服务并且无法运行它

java - Spring Rest Controller 字符串响应

python - 在 callbackURL 端点从 Google Glass 获取 "REPLY"通知

java - 使用操作栏发送数据 [Android]