java web项目前后端分离的跨域问题CORS

本文探讨了前后端分离的架构模式及其带来的优势,详细解释了跨域问题的成因,即同源策略限制,并介绍了CORS解决方案,包括响应头配置、Spring框架配置和自定义Filter实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

1:前后端分离:

2:前后端分离的好处:

3:跨域问题存在的原因:

4:跨域问题的解决方案CORS:

4.1、在web.xml中配置

4.2、通过WebMvcConfigurer

4.3 自定义Filter


1:前后端分离:

前后端分离并不只是开发模式,而是web应用的一种架构模式。在开发阶段,前后端工程师约定好数据交互接口,实现并行开发和测试;在运行阶段前后端分离模式需要对web应用进行分离部署,前后端之前使用HTTP或者其他协议进行交互请求。

2:前后端分离的好处:

1:最大的好处就是前端JS可以做很大部分的数据处理工作,对服务器的压力减小到最小。
2:后台错误不会直接反映到前台,错误接秒较为友好。
3:由于后台是很难去探知前台页面的分布情况,而这又是JS的强项,而JS又是无法独立和服务器进行通讯的。所以单单用后台去控     制整体页面,又或者只靠JS完成效果,都会难度加大,前后台各尽其职可以最大程度的减少开发难度。

3:跨域问题存在的原因:

  • 同源策略:

同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。

  • 跨域问题原因:

    跨域问题的根本原因:因为浏览器收到同源策略的限制,当前域名的js只能读取同域下的窗口属性。同源策略是针对浏览器设置的门槛。

4:跨域问题的解决方案CORS:

       跨域问题有多种解决方案:可参考https://www.cnblogs.com/sdcs/p/8484905.html

       由于其他方案多有限制,这里只讨论CORS(跨域资源共享)解决方案,CORS也已经成为主流的跨域解决方案。  

用于CORS中的Http的首部有如下几个:

  • 响应头

    • Access-Control-Allow-Origin: 允许跨域访问的域,可以是一个域的列表,也可以是通配符”*”;
    • Access-Control-Allow-Methods: 允许使用的请求方法,以逗号隔开;
    • Access-Control-Allow-Headers: 允许自定义的头部,以逗号隔开,大小写不敏感;
    • Access-Control-Expose-Headers: 允许脚本访问的返回头,请求成功后,脚本可以在XMLHttpRequest中访问这些头的信息
    • Access-Control-Allow-Credentials: 是否允许请求带有验证信息,XMLHttpRequest请求的withCredentials标志设置为true时,认证通过,浏览器才将数据给脚本程序。
    • Access-Control-Max-Age: 缓存此次请求的秒数。在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据,非常有用,大幅优化请求次数;
  • 请求头

    • Origin: 普通的HTTP请求也会带有,在CORS中专门作为Origin信息供后端比对,表明来源域,要与响应头中的Access-Control-Allow-Origin相匹配才能进行跨域访问;
    • Access-Control-Request-Method: 将要进行跨域访问的请求方法,要与响应头中的Access-Control-Allow-Methods相匹配才能进行跨域访问;
    • Access-Control-Request-Headers: 自定义的头部,所有用setRequestHeader方法设置的头部都将会以逗号隔开的形式包含在这个头中,要与响应头中的Access-Control-Allow-Headers相匹配才能进行跨域访问

方案:

跨域访问的请求头中存在Origin的字段,用来记录当前的访问域名,我们可以再服务端增加一个响应头Access-Control-Allow-Origin来告诉浏览器我们支持它获取就可以了。

实现:

4.1、在web.xml中配置

将在上述服务器中的web.xml上配置的filter,配置到自己的工程中。然后加入maven依赖,如下类似:

<dependency>
    <groupId>com.thetransactioncompany</groupId>
    <artifactId>cors-filter</artifactId>
    <version>2.5</version>
</dependency>

这样就完成了对跨域访问请求的支持,如果并不想对所有的请求都支持跨域访问,则可以在Filter的url-pattern中改变匹配到的url地址。

4.2、通过WebMvcConfigurer

在Spring中,使用这个接口可以通过定义回调方法来进行一些Spring MVC中要用到的配置,在里面用来支持CORS的方法是addCorsMappings(CorsRegistry registry),我们并不直接使用这个接口而是使用它的抽象实现类WebMvcConfigurerAdapter,这个类中给我们提供了WebMvcConfigurer接口中方法的空实现,我们可以直接填上自己的业务逻辑就可以直接使用。在这个回调方法中的参数是CorsRegistry,这个类可以帮助我们为相应的url地址提供CORS配置,关于这个方法可以放到Application启动类中,也可以单独放到一个类中。

在Application启动类中使用该方法,只需要在Application启动类中加入如下代码即可。

 

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/greeting-javaconfig").allowedOrigins("http://localhost:9000");
        }
    };
}

独自建立新类使用该方法,则需要配置一些注解,如下:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.springboot.demo" })
public class WebConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/*").allowedOrigins("http://localhost:8070");
    }

}

与在Application启动类中使用相比多了@Configuration@EnableWebMvc注解,这是因为@SpringBootApplication已经包含上述两个注解了,所以不需要重新加入。 
CorsRegistry中调用addmapping后会得到CorsRegistration类,这时候就可以使用链式调用可以对这个CORS配置进行origin、method、header、maxage等的限制,这里就不展开了。

4.3 自定义Filter

所有的方法归根结底就是拦截对接口的访问,所以如果你不想麻烦并且想深入了解CORS到底是怎样工作的,可以通过自定义Filter来实现,其实这也没有什么难的,就是在拦截器上通过对请求和响应加上一些Headers,这里就不说了。

### 若依框架前后端分离问题解决方案 #### CORS简介 资源共享(CORS,Cross-Origin Resource Sharing)是一种机制,它允许浏览器向不同源的服务器发出 XMLHttpRequest 请求。同源策略限制了从同一个源加载的文档或脚本如何与另一个源的资源进行交互[^1]。 #### 若依框架中的解决方式 在若依框架中,可以通过多种方式进行配置: 1. **使用 `@CrossOrigin` 注解** 在 Controller 层的方法或类上添加 `@CrossOrigin` 注解可以实现单个接口或整个控制器的支持。例如: ```java @RestController @RequestMapping("/example") @CrossOrigin(origins = "http://localhost:8080", maxAge = 3600) public class ExampleController { @GetMapping("/test") public String test() { return "Test Success"; } } ``` 上述代码表示 `/example/test` 接口允许来自 `http://localhost:8080` 的请求,并设置缓存时间为 3600 秒[^4]。 2. **全局配置 CORS 过滤器** 可以通过创建一个自定义的 Web 配置类来实现全局范围内的支持。以下是具体实现方法: ```java import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 对所有的路径生效 .allowedOrigins("*") // 允许所有名访问 .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 支持的 HTTP 方法 .maxAge(3600L); // 缓存时间 (单位秒) } @Bean public WebMvcConfigurer corsConfigurer() { return new WebMvcConfigurer() { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**").allowedOrigins("http://localhost:8080"); } }; } } ``` 此种方式适用于需要统一管理规则的情况[^3]。 3. **Nginx反向代理** 如果不想修改后端代码,也可以通过 Nginx 来解决问题。配置如下: ```nginx server { listen 80; server_name your-domain.com; location /api/ { proxy_pass http://backend-server/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-NginX-Proxy true; } } ``` 使用此方法可以让前端和后端看起来像是同一源,从而规避问题[^2]。 #### 注意事 - 当前主流推荐的方式是采用 CORS 技术,因为它更加灵活且易于维护。 - 如果涉及敏感数据传输,则需谨慎设置 `allowedOrigins` 参数,避免因开放过多权限而引发安全风险。 ```python print("以上为针对若依框架前后端分离时的问题解决方案") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值