Kotlin 和 Spring Boot 中的 CORS 预检错误

CORS Preflight Error In Kotlin and Springboot

这是针对以下错误的绝对最小测试用例:

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 应该处理的绝对最小应用程序。我不知道是什么问题。

试试这个:

@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
    }

}

CORS 在第一次处理时可能会令人头疼。这里有一些 useful information 帮助我理解它的含义。

如果您想要全局 CORS 配置,我建议您使用 @Configuration 而不是 class 注释。添加新的 class:

@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,但我认为您可以应付。 此外, 较旧的答案可能会有所帮助。