无法向Spring Boot服务器发送POST请求(HTTP报405,HTTPS正常)
问题描述
我开发了一个带控制器的Spring Boot应用,部署在域名上,遇到以下问题:
- 通过HTTP发送POST请求时返回405错误
- 通过HTTPS发送POST请求一切正常
- GET请求无论使用HTTP还是HTTPS都能正常工作
控制器代码如下:
@Slf4j @RestController @CrossOrigin("*") @Tag(name = "Quiz") @RequiredArgsConstructor @RequestMapping("/api/quiz") public class QuizController { private final QuizService quizService; @Operation( description = "Creating quiz", summary = "Creating new quiz by dto and sending message to users", responses = { @ApiResponse(description = "Success", responseCode = "201"), @ApiResponse(description = "Quiz with this name already exists", responseCode = "400")}) @PostMapping @ResponseStatus(HttpStatus.CREATED) public void createQuiz(@RequestBody QuizDataDTO quizDataDTO) { quizService.createQuiz(quizDataDTO); quizService.spreadQuiz(quizDataDTO.getTelegramUsersIds()); log.info("Create quiz with name {}", quizDataDTO.getQuizDTO().getQuizName()); } @Operation(description = "Get links", summary = "Getting all links from google sheets lists", responses = @ApiResponse(description = "Success", responseCode = "200")) @GetMapping("/links") @ResponseStatus(HttpStatus.OK) public List<QuizDetailsDTO> getAllQuizs() { log.info("Return all quiz"); return quizService.getAllQuizs(); } }
已尝试在配置文件中配置CORS,但无效果。
可能原因及解决方案
1. 反向代理(如Nginx)的HTTP转HTTPS重定向处理错误
这是最常见的原因:很多部署环境会配置Nginx将HTTP请求重定向到HTTPS,但默认的302重定向会把POST请求转为GET,导致目标路径没有对应的GET映射,返回405。
解决方法:
在Nginx配置中,对HTTP请求使用307 Temporary Redirect来重定向,它会保留原请求方法和请求体:
server { listen 80; server_name your-domain.com; return 307 https://$server_name$request_uri; }
如果需要更精细的控制,也可以针对POST方法单独处理:
server { listen 80; server_name your-domain.com; location / { if ($request_method = POST) { return 307 https://$server_name$request_uri; } return 301 https://$server_name$request_uri; } }
2. Spring Boot内置服务器(如Tomcat)的HTTP端口配置问题
检查Spring Boot的application.properties/application.yml中HTTP相关的配置,确认是否有对POST方法的限制:
- 确保没有自定义的
TomcatConnector配置拦截POST请求 - 检查是否启用了
security相关配置,是否对HTTP端口的POST请求做了拦截
3. 防火墙/安全组限制
确认服务器的防火墙或云服务商的安全组是否允许HTTP端口(默认80)的POST请求通过,有些安全规则可能只开放了HTTP的GET方法。
4. 全局HTTPS强制跳转的Spring配置问题
如果是通过Spring Security配置的HTTPS强制跳转,需要确保配置保留请求方法:
@Configuration public class SecurityConfig extends WebSecurityConfigurerAdapter { @Override protected void configure(HttpSecurity http) throws Exception { http .requiresChannel() .anyRequest() .requiresSecure() .and() .formLogin() .and() .csrf().disable(); // 根据实际情况调整CSRF配置 } @Bean public TomcatServletWebServerFactory servletContainer() { TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() { @Override protected void postProcessContext(Context context) { SecurityConstraint securityConstraint = new SecurityConstraint(); securityConstraint.setUserConstraint("CONFIDENTIAL"); SecurityCollection collection = new SecurityCollection(); collection.addPattern("/*"); securityConstraint.addCollection(collection); context.addConstraint(securityConstraint); } }; tomcat.addAdditionalTomcatConnectors(redirectConnector()); return tomcat; } private Connector redirectConnector() { Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol"); connector.setScheme("http"); connector.setPort(80); connector.setSecure(false); connector.setRedirectPort(443); return connector; } }
注意:这种方式默认会用302重定向,同样会导致POST转GET,建议还是用反向代理层处理重定向更可靠。
内容的提问来源于stack exchange,提问作者KripDo
相关产品推荐
相关产品推荐

