Kotlin 和 Spring Boot 中的 CORS 预检错误
Posted
技术标签:
【中文标题】Kotlin 和 Spring Boot 中的 CORS 预检错误【英文标题】:CORS Preflight Error In Kotlin and Springboot 【发布时间】:2021-09-09 19:43:22 【问题描述】:这是针对以下错误的绝对最小测试用例:
Access to fetch at 'http://localhost:8080/comment' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
首先,我从https://start.spring.io/下载以下项目
仅有的两个依赖项是 Spring Web 和 Rest Repositories
然后我将以下内容添加到我的 DemoApplication.kt
文件中:
package com.example.demo //original line
import org.springframework.boot.autoconfigure.SpringBootApplication //original line
import org.springframework.boot.runApplication //original line
import org.springframework.web.bind.annotation.GetMapping //added line
import org.springframework.web.bind.annotation.PostMapping //added line
import org.springframework.web.bind.annotation.RestController //added line
import org.springframework.web.bind.annotation.CrossOrigin //added line
import org.springframework.web.bind.annotation.RequestMapping //added line
import org.springframework.web.bind.annotation.RequestBody //added line
@SpringBootApplication //original line
class DemoApplication //original line
fun main(args: Array<String>) //original line
runApplication<DemoApplication>(*args) //original line
//original line
//below all added lines
@RestController
@CrossOrigin(origins = ["http://localhost:3000"], maxAge=3600, allowCredentials = "true")
@RequestMapping("/test")
public class RequestTest
@GetMapping
// @CrossOrigin(origins = ["http://localhost:3000"], maxAge=3600, allowCredentials = "true")
fun stringfunc():String
println("inside the index of requesttest")
return "some string"
@RequestMapping("/comment")
// @CrossOrigin(origins = ["http://localhost:3000"], maxAge=3600, allowCredentials = "true")
fun getComment() : String
val comment: String = "i hope this works"
return comment
这里是 pom.xml
文件,该文件未从下载的应用程序中修改 -
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>11</java.version>
<kotlin.version>1.5.20</kotlin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
<artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<sourceDirectory>$project.basedir/src/main/kotlin</sourceDirectory>
<testSourceDirectory>$project.basedir/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
</configuration>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>$kotlin.version</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
构建输出显示没有错误并且服务器正在运行。
我的 javascript 获取请求是 -
const fetchrequest = () =>
fetch('http://localhost:8080/comment')
.then(response => response.json())
.then(data => console.log(data))
这应该是@CrossOrigin
应该使用的绝对最小的应用程序。不知道是什么问题。
【问题讨论】:
您似乎在混合 Spring 的 Web 框架,因为您同时依赖于 starter-web 和 starter-webflux。当两者都存在时,首选基于 Servlet 的 starter-web。这意味着您的基于 WebFlux 的 WebFilter 无效。我建议将您的应用程序剥离到重现问题所需的最低限度。 我已经删除了 starter-webflux 并且还删除了 spring-security。仍然有相同的预检错误。我在上面复制了一个最小的应用程序。 CORS 仅涉及 Web 层,因此删除 mysql、PostgreSQL 和 JPA 依赖项,您可能还可以删除验证和 devtools 依赖项。 ...并且您有一个类级别的 CORS 注释以及方法级别的 CORS 注释,因此您可以尝试其中一个而不是两者,并且因为您的测试只是关于 GET @ 987654331@去掉其他方法,用@GetMapping('/comment')
代替@RequestMapping
。
【参考方案1】:
试试这个:
@SpringBootApplication
class KotlinServerApplication
fun main(args: Array<String>)
runApplication<KotlinServerApplication>(*args)
@RestController
@CrossOrigin(origins = ["http://localhost:3000"], maxAge=3600, allowCredentials = "true")
public class RequestTest
@GetMapping("/comment")
fun getComment() : Comment
val comment = Comment(
author = "test",
content = "test",
)
return comment
【讨论】:
我在上面复制了一个最小的测试用例示例。仍然出现同样的错误。 发现问题 - fetch('localhost:8080/test/comment')。鉴于这是正确的答案,我会给予你信任。【参考方案2】:第一次处理 CORS 时可能会让人头疼。这里有一些 useful information 帮助我理解了它的含义。
如果您想要全局 CORS 配置,我建议您使用 @Configuration
而不是类注释。添加一个新类:
@Configuration
@ComponentScan
public class RestConfiguration
@Bean
public WebMvcConfigurer corsConfigurer()
return new WebMvcConfigurer()
@Override
public void addCorsMappings(CorsRegistry registry)
registry.addMapping("/**").allowedOrigins("https://my.allowed.origin.com");
;
它是 Java,但我认为您可以处理它。 此外,this 较早的答案可能会有所帮助。
【讨论】:
以上是关于Kotlin 和 Spring Boot 中的 CORS 预检错误的主要内容,如果未能解决你的问题,请参考以下文章
为啥@JacksonXmlProperty 使用 Kotlin 忽略 Spring Boot 中的参数?
kotlin + Spring boot 中的单元测试休息控制器
在 pom.xml 中为 Kotlin 中的 Spring Boot 项目指定 Main 类
具有不可变属性的@ConstructorBinding 不适用于 Spring Boot Kotlin 中的 @Value @ConfigurationProperties