跨域问题解决

ops/2024/12/29 0:59:58/

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 原理介绍:
  • 1.@CrossOrigin注解
  • 2.实现WebMvcConfigurer接口
  • 3.使用过滤器
  • 4.vue代理服务器
  • 总结


前言

跨域问题由浏览器的同源策略引起,浏览器限制默认不能给不同源(协议、ip、端口任意一个不同)发送请求,导致前后端无法正常通信。


原理介绍:

本质是服务器处理并返回了响应数据后,浏览器发现是来自不同源的响应数据,所以选择拒接。这个时候我们需要在响应数据的响应头中添加额外配置来让浏览器能成功接收。
所以我们不同的解决方式本质都是要为响应数据的响应头添加额外信息。

但我们现在的主流开发方式是前后端分离,我们使用ajax请求来获取数据时都是在发送跨域请求,所以这是我们不得不解决的问题。
针对这个问题,在springboot和vue的项目结构下,我们有多种解决方案。

1.@CrossOrigin注解

直接在控制类或者控制类的方法上添加@CrossOrigin注解来实现,可以额外指定可以接收哪些域名发送的请求。
以下是接收所有跨域请求:

java">@RestController  
@RequestMapping("/user")  
@CrossOrigin(origins = "*")  
public class UserController {  // 控制器方法  
}

以下是接收特定域名的跨域请求:

java">@PostMapping("/login")
@CrossOrigin(origins = "http://example.com")
public ResponseEntity<?> login(@RequestBody UserCredentials credentials) {
// 控制器方法
}

2.实现WebMvcConfigurer接口

webMvcConfigurer接口中我们可以重写addCorsMappings方法来配置跨域请求处理方法

java">@Configuration  
public class WebConfig implements WebMvcConfigurer {  @Override  public void addCorsMappings(CorsRegistry registry) {  registry.addMapping("/**") // 对所有路径生效  .allowedOrigins("*") // 允许所有源地址  .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的请求方法  .allowedHeaders("*") // 允许的请求头  .allowCredentials(true) // 是否允许发送Cookie  .maxAge(3600); // 预检请求的有效期  }  
}

3.使用过滤器

我们可以自己创建一个过滤器,在过滤器中对即将返回的响应数据添加额外的响应头配置。然后将其交给IOC容器管理。
案例代码:

java">import org.springframework.boot.web.servlet.FilterRegistrationBean;  
import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  import javax.servlet.*;  
import javax.servlet.annotation.WebFilter;  
import javax.servlet.http.HttpServletResponse;  
import java.io.IOException;  @Configuration  
public class CorsConfig {  @Bean  public FilterRegistrationBean<CorsFilter> corsFilter() {  FilterRegistrationBean<CorsFilter> registrationBean = new FilterRegistrationBean<>();  registrationBean.setFilter(new CorsFilter());  registrationBean.addUrlPatterns("/*");  registrationBean.setOrder(1); // 设置过滤器的顺序  return registrationBean;  }  // 也可以使用@WebFilter注解直接定义过滤器,但在此示例中我们通过Java配置类来注册它  public static class CorsFilter implements Filter {  @Override  public void init(FilterConfig filterConfig) throws ServletException {  // 初始化过滤器(可选)  }  @Override  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)  throws IOException, ServletException {  HttpServletResponse httpResponse = (HttpServletResponse) response;  httpResponse.setHeader("Access-Control-Allow-Origin", "*");  httpResponse.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");  httpResponse.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");  httpResponse.setHeader("Access-Control-Allow-Credentials", "true");  httpResponse.setHeader("Access-Control-Max-Age", "3600");  // 放行chain.doFilter(request, response);  }  @Override  public void destroy() {  // 销毁过滤器(可选)  }  }  
}

这样手动添加响应头信息可以帮助我们理解解决跨域问题的本质,但其实spring中已经为我们提供了一个类来帮助我们完成这些工作——CorsFilter
我们只要简单的创建并配置一个CorsFilter对象并其交给IOC管理即可。
案例代码:

java">import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;/*** 跨域配置*/
@Configuration
public class CorsConfig {@Beanpublic CorsFilter corsFilter() {UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();CorsConfiguration corsConfiguration = new CorsConfiguration();corsConfiguration.addAllowedOrigin("*"); // 1 设置访问源地址corsConfiguration.addAllowedHeader("*"); // 2 设置访问源请求头corsConfiguration.addAllowedMethod("*"); // 3 设置访问源请求方法source.registerCorsConfiguration("/**", corsConfiguration); // 4 对接口配置跨域设置return new CorsFilter(source);}
}

4.vue代理服务器

前面说到的几种后端处理跨域请求的方法,本质都是为响应数据添加额外响应头数据来让浏览器接收数据。
但这里使用vue代理服务器的方式解决跨域请求,实际是使用代理服务器来转发我们的请求。
我们可以在vue.config.js(vue2)或vite.config.js(vue3)文件中进行配置.
案例配置:

devServer: {//配置代理,解决跨域问题proxy: {'/api': {//vue项目中所有路径中带api的请求都会进行转发target: 'http://localhost:8080',//目标地址changeOrigin: true,//是否跨域pathRewrite: { '^/api': '' }//路径重写}}}

总结

以上就是在javaweb开发中可以解决跨域问题的几种方式。


http://www.ppmy.cn/ops/145786.html

相关文章

Ruby 数据库访问 - DBI 教程

Ruby 数据库访问 - DBI 教程 介绍 DBI&#xff08;Database Interface&#xff09;是Ruby语言中用于访问数据库的模块。它提供了一个统一的接口&#xff0c;允许Ruby程序与各种数据库进行交互。DBI的设计哲学是简洁和灵活&#xff0c;使得开发者能够轻松地编写数据库访问代码…

微信小程序打印生产环境日志

微信小程序打印生产环境日志 新建一个log.js文件&#xff0c;写入以下代码&#xff1a; let log wx.getRealtimeLogManager ? wx.getRealtimeLogManager() : nullmodule.exports {debug() {if (!log) returnlog.debug.apply(log, arguments)},info() {if (!log) returnlog.i…

探索寄存器读写函数:writeb, writew, writel 与 readb, readw, readl

本章目录 函数介绍读寄存器函数写寄存器函数 示例代码总结 在嵌入式系统开发中&#xff0c;与硬件直接交互是常见的需求。为了实现对硬件寄存器的读写操作&#xff0c;开发者通常会使用一些特定的函数。这些函数允许我们以字节、半字&#xff08;2字节&#xff09;或字&#xf…

Animated Drawings:让纸上的角色动起来

前言 今天介绍的这个工具非常的有意思&#xff1a;它可以让我们在纸上绘画的角色动起来。先一起来看看效果&#xff1a; 准备 首先&#xff0c;我们先准备一张绘画。可以在纸上进行绘制&#xff0c;也可以在电子设备上进行绘制。绘制内容不限&#xff0c;在这里为了方便演示&am…

(补)算法刷题Day24: BM61 矩阵最长递增路径

题目链接 思路 方法一&#xff1a;dfs暴力回溯 使用原始used数组4个方向遍历框架 &#xff0c; 全局添加一个最大值判断最大的路径长度。 方法二&#xff1a;加上dp数组记忆的优雅回溯 抛弃掉used数组&#xff0c;使用dp数组来记忆遍历过的节点的最长递增路径长度。每遍历到已…

怎么学习数据结构与算法?

数据结构与算法 提及数据结构与算法&#xff0c;许多人可能会不自觉地皱起眉头。似乎在不知不觉中&#xff0c;以字节跳动为代表的一批公司&#xff0c;在面试环节开始了一场针对算法的连环盘问。若非事先系统地刷过一系列算法题目&#xff0c;想要轻松通过这一关&#xff0c;…

解锁 Claude 的无限潜力:Prompt Engineering 从入门到精通

在人工智能领域&#xff0c;大型语言模型&#xff08;LLM&#xff09;如 Claude 的崛起&#xff0c;为我们带来了前所未有的机遇。然而&#xff0c;如何有效地与这些强大的模型进行交互&#xff0c;使其发挥出最大的潜力&#xff0c;成为了关键。Prompt Engineering&#xff08…

k8s创建单例redis设置密码

在 Kubernetes (k8s) 中创建一个带密码的单例 Redis 部署&#xff0c;你可以通过定义一个包含 Redis 容器、服务(Service)以及必要配置(如密码设置)的 YAML 文件来实现。以下是一个基本的示例&#xff0c;展示了如何配置这些组件。 1. 创建 Redis 部署(Deployment) 首先&#x…