You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java SpringBoot部署后CORS跨域问题求助:缺失Access-Control-Allow-Origin头

Render部署React+SpringBoot后CORS跨域问题,已尝试多种方案仍未解决

已查阅Stack Overflow上2页同类问题帖,尝试了多种CORS处理方案,但仍未解决问题。

在Render平台部署React前端与Java SpringBoot后端后,前端向后端发起HTTP请求时出现如下报错:

Access to XMLHttpRequest at 'https://movie-gold-v2.onrender.com/api/v1/movies' from origin 'https://movie-gold-v1.onrender.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource。

以下是我尝试过的所有方案:

1. 控制器添加@CrossOrigin注解

在MovieController上尝试过多种@CrossOrigin配置,但均无效,目前已注释:

@RestController
//@CrossOrigin(origins = "https://movie-gold-v1.onrender.com", allowedHeaders = "*")
//@CrossOrigin(origins = {"https://movie-gold-v1.onrender.com"})
//@CrossOrigin(origins = "*")
@RequestMapping("/api/v1/movies")
public class MovieController {
    // ... 控制器方法
}

2. WebConfig全局CORS配置

创建了WebConfig.java全局配置类:

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("https://movie-gold-v1.onrender.com")
                .allowedMethods("HEAD","GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*");
    }
}

3. DevConfiguration环境专属配置

针对development环境创建配置类:

@Configuration
@Profile("development")
public class DevConfiguration implements WebMvcConfigurer {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedMethods("GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS").allowedOrigins("https://movie-gold-v1.onrender.com");
    }
}

4. CorsConfig Bean配置

通过Bean方式配置CORS:

@Component
public class CorsConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry
                        .addMapping("/**")
                        .allowedMethods(CorsConfiguration.ALL)
                        .allowedHeaders(CorsConfiguration.ALL)
                        .allowedOriginPatterns(CorsConfiguration.ALL);
            }
        };
    }
}

相关代码片段

MovieController完整代码

@RestController
//@CrossOrigin(origins = "https://movie-gold-v1.onrender.com", allowedHeaders = "*")
//@CrossOrigin(origins = {"https://movie-gold-v1.onrender.com"})
//@CrossOrigin(origins = "*")
@RequestMapping("/api/v1/movies")

public class MovieController {

    @Autowired
    private MovieService service;

    @GetMapping
    public ResponseEntity<List<Movie>> getMovies() {
        List<Movie> movies = service.findAllMovies();
        return new ResponseEntity<>(movies, HttpStatus.OK);
    }

    @GetMapping("/{imdbId}")
    public ResponseEntity<Movie> getSingleMovie(@PathVariable String imdbId) {
        Optional<Movie> movie = service.findMovieByImdbId(imdbId);
        if (movie.isPresent()) {
            Movie fetchedMovie = movie.get();
            return new ResponseEntity<>(fetchedMovie, HttpStatus.OK);
        } else {
            return new ResponseEntity<>(HttpStatus.NOT_FOUND);
        }
    }
}

前端Axios配置

import axios from 'axios';

export default axios.create({
    // baseURL:'http://localhost:8080',
    baseURL: 'https://movie-gold-v2.onrender.com',
});

前端App.js请求代码

function App() {

  const [movies, setMovies] = useState();
  const [movie, setMovie] = useState();
  const [reviews, setReviews] = useState([]);

  const getMovies = async () =>{
    
    try
    {
      // const response = await api.get("/api/v1/movies");
      const response = await api.get("https://movie-gold-v2.onrender.com/api/v1/movies");

      setMovies(response.data);

    } 
    catch(err)
    {
      console.log(err);
    }
  }

  const getMovieData = async (movieId) => {
     
    try 
    {
        //  const response = await api.get(`/api/v1/movies/${movieId}`);
         const response = await api.get(`https://movie-gold-v2.onrender.com/api/v1/movies/${movieId}`);

        const singleMovie = response.data;

        setMovie(singleMovie);

        setReviews(singleMovie.reviews);
        

    } 
    catch (error) 
    {
      console.error(error);
    }

  }

  useEffect(() => {
    getMovies();
  },[])

  return (
    <div className="App">
      <Header/>
      <Routes>
          <Route path="/" element={<Layout/>}>
            <Route path="/" element={<Home movies={movies} />} ></Route>
            <Route path="/Trailer/:ytTrailerId" element={<Trailer/>}></Route>
            <Route path="/Reviews/:movieId" element ={<Reviews getMovieData = {getMovieData} movie={movie} reviews ={reviews} setReviews = {setReviews} />}></Route>
            <Route path="*" element = {<NotFound/>}></Route>
          </Route>
      </Routes>

    </div>
  );
}

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>3.1.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>unicorndev</groupId>
    <artifactId>movies</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>movies</name>
    <description>A simple API related to movies</description>
    <properties>
        <java.version>20</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
            <version>3.1.0</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongodb-driver-sync</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>me.paulschwarz</groupId>
            <artifactId>spring-dotenv</artifactId>
            <version>2.5.4</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <version>3.8.1</version>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <source>17</source>
                    <target>17</target>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

几乎尝试了所有可行方案,卡了近一周,实在不清楚遗漏了什么,恳请帮忙排查,万分感谢!

内容的提问来源于stack exchange,提问作者Jess Y.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 09:24:55