Java 中的跨域问题解决方法

2025-05-28 03:50
文章标签 java 问题 方法 解决 跨域

本文主要是介绍Java 中的跨域问题解决方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Java中的跨域问题解决方法》跨域问题本质上是浏览器的一种安全机制,与Java本身无关,但Java后端开发者需要理解其来源以便正确解决,下面给大家介绍Java中的跨域问题解决方法,感兴趣的朋友一起...

1、Java 中跨域问题的来源

跨域问题(Cross-Origin Resource Sharing, CORS)本质上是浏览器的一种安全机制,与Java本身无关,但Java后端开发者需要理解其来源以便正确解决。以下是跨域问题的详细来源分析:

1.1. 浏览器同源策略(Same-Origin Policy)

  • 根本来源:浏览器出于安全考虑实施的同源策略
  • 同源定义协议(http/https)+域名+端口三者完全相同
  • 限制内容:限制不同源的DOM访问,限制不同源的AJAX请求,限制不同源的Cookie/LocalStorage访问

1.2. Java后端常见的跨域触发场景

1.2.1 前后端分离架构

Java 中的跨域问题解决方法

开发时前端与后端运行在不同端口

生产环境前端与后端可能部署在不同域名下

1.2.2 微服务架构

Java 中的跨域问题解决方法

网关与服务可能在不同域
服务间调用也可能涉及跨域

1.2.3 第三方API集成

调用外部服务如支付接口、地图API等

1.3. Java中具体的跨域表现

1.3.1 典型错误

Access to XMLHttpRequest at 'http://api.example.com' from origin 'http://frontend.com' 
has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present 
on the requested resource.

1.3.2 触发条件

Java 中的跨域问题解决方法

1.4. Java特有的跨域问题来源

1.4.1 Spring Security默认配置

Spring Security默认启用CSRF保护
会与CORS机制产生冲突

1.4.2 Servlet容器行为

Tomcat/Jetty等容器默认不带CORS头
过滤器链顺序可能影响CORS处理

1.4.3 传统Java Web应用

JSP时代页面和后端同源,现代前后端分离导致问题显现

1.5. 为什么需要Java端解决

浏览器行为不可控:同源策略是浏览器强制实施的
安全责任在后端:哪些源可以访问应由后端决定
灵活控制需求:不同接口可能需要不同的跨域策略

1.6. 特殊注意事项

Cookie跨域:需要设置Access-Control-Allow-Credentials: true
自定义头跨域:需在Access-Control-Allow-Headers中声明
缓存问题:合理设置Access-Control-Max-Age提高性能

2、Java 中解决跨域问题的方法

跨域问android题是由于浏览器的同源策略(Same-Origin Policy)导致的,当你的前端应用(如运行在 http://localhost:8080)尝试访问不同源(如 http://api.example.com)的后端API时,浏览器会阻止这种请求。以下是Java中常见的跨域解决方案:

2.1. Spring Boot 解决方案

2.1.1 使用 @CrossOrigin 注解

@RestController
@RequestMapping("/api")
public class MyController {
    // 允许单个方法跨域
    @CrossOrigin(origins = "http://localhost:3000")
    @GetMapping("/hello")
    public String hello() {
        return "Hello, CORS!";
    }
    // 允许整个控制器跨域
    @CrossOrigin(origins = "http://localhos编程t:3000")
    @GetMapping("/another")
    public String another() {
        return "Another endpoint";
    }
}

2.1.2 全局配置跨域

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")  // 所有路径
                .allowedOrigins("http://localhost:3000", "https://example.com")  // 允许的源
                .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS")  // 允许的方法
                .allowedHeaders("*")  // 允许的请求头
                .allowCredentials(true)  // 允许携带凭证(cookie等)
                .maxAge(3600);  // 预检请求的缓存时间(秒)
    }
}

2.2. 传统 Servlet 解决方案

2.2.1 使用 Filter

/**
 * CORS跨域过滤器配置
 * 用于处理浏览器跨域请求的支持
 * 过滤器会拦截所有请求(/*)并添加CORS响应头
 */
@WebFilter("/*")  // 拦截所有请求
public class CorsFilter implements Filter {
    /**
     * 过滤器核心方法,处理请求和响应
     * @param req ServletRequest对象
     * @param res ServletResponse对象
     * @param chain FilterChain对象,用于继续过滤器链
     */
    @Override
    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) 
            throws IOException, ServletException {
        // 类型转换为HTTP相关的请求/响应对象
        HttpServletResponse response = (HttpServletResponse) res;
        HttpServletRequest request = (HttpServletRequest) req;
        // 设置允许所有域访问(生产环境应替换为具体域名)
        response.setHeader("Access-Control-Allow-Origin", "*");
        // 设置允许的HTTP方法
        response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");
        // 设置预检请求的缓存时间(1小时)
        response.setHeader("Access-Control-Max-Age", "3600");
        // 设置允许的请求头(包括自定义头)
        response.setHeader("Access-Control-Allow-Headers", "authorization, content-type, xsrf-token");
        // 设置允许前端访问的响应头(暴露自定义头)
        response.addHeader("Access-Control-Expose-Headers", "xsrf-token");
        // 处理OPTIONS预检请求
        if ("OPTIONS".equals(request.getMethod())) {
            // 直接返回200状态码,不继续过滤器链
            response.setStatus(HttpServletResponse.SC_OK);
        } else {
            // 非OPTIONS请求,继续过滤器链
            chain.doFilter(req, res);
        }
    }
    /**
     * 过滤器初始化方法(可留空)
     * @param filterConfig 过滤器配置对象
     */
    @Override 
    public void init(FilterConfig filterConfig) {
        // 初始化逻辑(如有需要)
    }
    /**
     * 过滤器销毁方法(可留空)
     */
    @Override 
    public void destroy() {
        // 清理资源逻辑(如有需要)
    }
}

2.3. Spring Security 解决方案

如果你的应用使用了Spring Security,需要在安全配置中添加CORS支持:

/**
 * Spring Security 安全配置类
 * 用于配置应用的安全策略和CORS跨域设置
 */
@Configuration  // 标记为Spring配置类
@EnableWebSeandroidcurity  // 启用Spring Security的Web安全支持
public class SecurityConfig extends WebSecurityConfigurerAdapter {
    /**
     * 配置HTTP安全策略
     * @param http HttpSecurity对象,用于配置安全策略
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http
            // 启用CORS支持(使用下面定义的corsConfigurationSource bean)
            .cors().and()  
            // 禁用CSRF防护(跨站请求伪造),因为API通常使用token验证而非session
            // 注意:如果前端与后端同域且使用session,应该保持启用
            .csrf().disable()  
            // 开始配置请求授权规则
            .authorizeRequests()
                // 允许/api/public/开头的URL无需认证
                .antMatchers("/api/public/**").permitAll()  
                // 其他所有请求都需要认证
                .anyRequest().authenticated();
    }
    /**
     * 配置CORS跨域设置
     * @return CorsConfigurationSource 跨域配置源
     */
    @Bean
    public CorsConfigurationSource corsConfigurationSource() {
        // 创建CORS配置对象
        CorsConfiguration configuration = new CorsConfiguration();
        // 设置允许的源(前端地址),可以添加多个
        configuration.setAllowedOrigins(Arrays.asList("http://localhost:3000"));
        // 设置允许的HTTP方法
        configuration.setAllowedMethods(Arrays.asList(
            "GET",      // 获取资源
            "POST",     // 创建资源
            "PUT",      // 更新资源
            "DELETE",   // 删除资源
            编程"OPTIONS"   // 预检请求
        ));
        // 设置允许的请求头(*表示所有)
        configuration.setAllowedHeaders(Arrays.asList("*"));
        // 允许发送凭据(cookie、认证信息等)
        // 注意:当设置为true时,allowedOrigins不能为*
        configuration.setAllowCredentials(true);
        // 创建基于URL的CORS配置源
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        // 对所有URL路径应用上述CORS配置
        source.registerCorsConfiguration("/**", configuration);
        return source;
    }
}

2.4. 注意事项

生产环境:不要使用 * 作为允许的源,应该明确指定允许的域名
凭证:如果前端需要发送cookie等凭证信息,需要设置 allowCredentials(true),并且不能使用 * 作为允许的源
预检请求:对于复杂请求(如带自定义头的请求),浏览器会先发送OPTIONS预检请求
缓存:合理设置 maxAge 可以减少预检请求的次数

2.5. 测试跨域是否成功

在浏览器开发者工具中检查响应头是否包含:

Access-Control-Allow-Origin: http://your-frontend-domain
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: content-type

Spring Boot应用推荐使用编程全局配置或Spring Security配置的方式。

到此这篇关于Java 中的跨域问题的文章就介绍到这了,更多相关Java 跨域内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于Java 中的跨域问题解决方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1154813

相关文章

JAVA中安装多个JDK的方法

《JAVA中安装多个JDK的方法》文章介绍了在Windows系统上安装多个JDK版本的方法,包括下载、安装路径修改、环境变量配置(JAVA_HOME和Path),并说明如何通过调整JAVA_HOME在... 首先去oracle官网下载好两个版本不同的jdk(需要登录Oracle账号,没有可以免费注册)下载完

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

Java中Integer128陷阱

《Java中Integer128陷阱》本文主要介绍了Java中Integer与int的区别及装箱拆箱机制,重点指出-128至127范围内的Integer值会复用缓存对象,导致==比较结果为true,下... 目录一、Integer和int的联系1.1 Integer和int的区别1.2 Integer和in

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

nginx 负载均衡配置及如何解决重复登录问题

《nginx负载均衡配置及如何解决重复登录问题》文章详解Nginx源码安装与Docker部署,介绍四层/七层代理区别及负载均衡策略,通过ip_hash解决重复登录问题,对nginx负载均衡配置及如何... 目录一:源码安装:1.配置编译参数2.编译3.编译安装 二,四层代理和七层代理区别1.二者混合使用举例

JSONArray在Java中的应用操作实例

《JSONArray在Java中的应用操作实例》JSONArray是org.json库用于处理JSON数组的类,可将Java对象(Map/List)转换为JSON格式,提供增删改查等操作,适用于前后端... 目录1. jsONArray定义与功能1.1 JSONArray概念阐释1.1.1 什么是JSONA

Java JDK1.8 安装和环境配置教程详解

《JavaJDK1.8安装和环境配置教程详解》文章简要介绍了JDK1.8的安装流程,包括官网下载对应系统版本、安装时选择非系统盘路径、配置JAVA_HOME、CLASSPATH和Path环境变量,... 目录1.下载JDK2.安装JDK3.配置环境变量4.检验JDK官网下载地址:Java Downloads

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap