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

React+Spring Boot跨域问题:GET请求浏览器报错但Postman正常

问题分析与解决:React前端调用Spring Boot后端的CORS问题

问题背景

React前端(http://localhost:8081)向Spring Boot后端接口http://localhost:8080/api/projects/admin/toinspection发送GET请求时触发CORS报错,Postman中请求正常,但浏览器报错:

Access to XMLHttpRequest at 'http://localhost:8080/api/projects/admin/toinspection' from origin 'http://localhost:8081' has been blocked by CORS policy: The response to the preflight request doesn't pass the access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

相关代码片段

React前端代码(ProjectPage.tsx)

const ProjectsPage = () => {

    const [projectsData, setProjectsData] = useState<ProjectsData[]>([])
    const projectsUrl = 'http://localhost:8080/api/projects/admin/toinspection'


    useEffect(() => {
        fetchData().then(r => console.log(r))
    }, []);

    const fetchData = async() => {
            const token = Cookies.get('token')
            const response = await axios.get<ProjectsData[]>(projectsUrl, {
                headers: {
                    "Content-Type": "application/json",
                    Authorization: `Bearer ${token}`,
                },
                withCredentials: true
            })
            setProjectsData(response.data)
        }

    return (
        <div>
            <AdminPageTemplate type="projects" children={<AdminModContent data={projectsData}/>}/>
        </div>
    );
};

export default ProjectsPage;

React组件代码(AdminModContent.tsx)

const AdminModContent: React.FC<ModeratorContentProps> = ({ data }) => {
    if (!data || data.length === 0) {
        return (
            <div className={styles.adminModContact__empty}>
                No content to moderate
            </div>
        );
    }

    const renderContent = (item: ContentItem) => {
        if (!item) return null;

        switch (item.type) {
            case "projects":
                return (
                    <div key={item.id} className={styles.adminModContact__projects}>
                        <p>ID: {item.id}</p>
                        <h3>Project: {item.title}</h3>
                        <p>Tech Stack: {item.technologyStack}</p>
                        <p>Description: {item.mainText}</p>
                        <p>Wishes: {item.wishes}</p>
                        <div className={styles.adminModContact__actions}>

                        </div>
                    </div>
                );
    };

    return (
        <div className={styles.adminModContact}>
            {data.map(item => renderContent(item))}
        </div>
    );
};

export default AdminModContent;

Spring Boot CORS配置(CorsConfig.java)

@Bean
public WebMvcConfigurer getWebMvcConfigurer(){
    return new WebMvcConfigurer() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**")
                    .allowedOrigins("http://localhost:8081")
                    .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")
                    .allowedHeaders("*")
                    .allowCredentials(true);
        }
    };
}

问题原因及解决思路

  1. 预检请求未被正确处理:浏览器发送的OPTIONS预检请求可能被自定义拦截器(如登录校验拦截器)优先拦截,导致响应未携带CORS头。
  2. CORS配置未生效:检查CorsConfig类是否添加了@Configuration注解,没有的话Spring不会加载该配置。
  3. 不必要的请求头触发预检:GET请求无需设置Content-Type: application/json,这个自定义头会触发预检请求,若后端未正确处理则报错。
  4. 配置优先级问题:WebMvcConfigurer的CORS配置优先级低于过滤器,若存在其他过滤器可能导致配置不生效。

具体解决方案

  • 确保配置类被Spring扫描:给CorsConfig添加@Configuration注解,让Spring识别为配置类。
  • 调整Axios请求头:移除GET请求中的Content-Type头,避免触发不必要的预检:
    const response = await axios.get<ProjectsData[]>(projectsUrl, {
        headers: {
            Authorization: `Bearer ${token}`,
        },
        withCredentials: true
    })
    
  • 改用CorsFilter提升优先级:替换原WebMvcConfigurer配置为CorsFilter,确保CORS处理优先于其他拦截器:
    @Configuration
    public class CorsConfig {
        @Bean
        public CorsFilter corsFilter() {
            CorsConfiguration config = new CorsConfiguration();
            config.setAllowedOrigins(Collections.singletonList("http://localhost:8081"));
            config.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS"));
            config.setAllowedHeaders(Collections.singletonList("*"));
            config.setAllowCredentials(true);
    
            UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
            source.registerCorsConfiguration("/**", config);
            return new CorsFilter(source);
        }
    }
    
  • 验证预检请求响应:在浏览器开发者工具Network标签中查看OPTIONS请求的响应头,确认是否包含Access-Control-Allow-Origin等CORS相关字段,排查配置是否生效。

内容的提问来源于stack exchange,提问作者fpbidni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 01:43:17