您的位置:首页 > 新闻 > 热点要闻 > Springboot处理跨域请求

Springboot处理跨域请求

2024/12/31 1:06:22 来源:https://blog.csdn.net/m0_64289188/article/details/140800030  浏览:    关键词:Springboot处理跨域请求

文章目录

    • 概要
    • 同源策略
    • 跨域问题复现
    • 解决跨域
      • 方法1
      • 方法2
      • 方法3
    • jwt拦截器验证token
    • 防止请求存在缓存

概要

跨域请求(Cross-Origin Requests)指的是在一个网页中加载的资源来自与当前网页不同的域、协议或端口。浏览器出于安全考虑,默认会限制这些跨域请求,这种限制称为同源策略(Same-Origin Policy)。

同源策略

同源策略要求一个网页只能与其源相同的资源进行交互,即:

  1. 域名相同
  2. 协议相同(如 HTTP 和 HTTPS)
  3. 端口相同

注意:只要域名 端口 协议一个不同就跨域了

跨域问题复现

前端:

<template><div><button @click="getData">点击发送get请求</button><h1>{{ data }}</h1></div>
</template><script setup lang="ts" name="Child">
import http from "axios";
import { ref } from 'vue'
let baseUrl = "http://localhost:8899/api"
let data = ref("")
function getData() {http.get(baseUrl + "/get").then(response => {data.value = response.data;}).catch(error => {console.log(error);})
}
</script>

后端:

@RestController
@RequestMapping(value = "/api")
public class TestController {@GetMapping(value = "/get")public String get() {return "get method";}
}

在这里插入图片描述

解决跨域

方法1

类或方法上添加@CrossOrigin(value="http://localhost:5173/")

应用级别:将 @CrossOrigin 注解放在类级别,意味着该类中的所有端点都允许来自指定来源的跨域请求。
方法级别:可以将 @CrossOrigin 注解放在特定方法上,以便仅允许某些特定方法的跨域请求。

@RestController
@RequestMapping(value = "/api")
@CrossOrigin(value="http://localhost:5173/")
public class TestController {@GetMapping(value = "/get")public String get() {return "get method";}

要是每一个类都写挺麻烦的。

方法2

写一个配置类放入容器

@Configuration
public class CrossConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/**") //指定允许跨域请求的路径模式.allowedOrigins("http://localhost:5173/").allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("*").allowCredentials(true); //指示是否允许发送凭据(如 Cookies、Authorization 头等)}
}

方法3

过滤器

@Component
public class CorsFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {HttpServletResponse res = (HttpServletResponse) response;HttpServletRequest req = (HttpServletRequest) request;res.setHeader("Access-Control-Allow-Origin", "http://localhost:5173");res.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS");res.setHeader("Access-Control-Allow-Headers", "Origin, Content-Type, Accept, Authorization");res.setHeader("Access-Control-Allow-Credentials", "true");// OPTIONS 预检请求,服务器会返回 200 状态码if ("OPTIONS".equalsIgnoreCase(req.getMethod())) {res.setStatus(HttpServletResponse.SC_OK);return;}chain.doFilter(request, response);}
}

jwt拦截器验证token

可能会遇到jwt验证token失败

可以加上预检请求

if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {return true;
}
@Component
public class InterceptorHandleConfig implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {if ("OPTIONS".equalsIgnoreCase(request.getMethod())) {return true;}String token = request.getHeader("Authorization");if (token == null) {response.setStatus(401);return false;}boolean verify = JWTUtil.verify(token, "123456".getBytes());if (!verify) {response.setStatus(401);return false;}return true;}
}

当然可以直接使用filter
Filter 是属于 Servlet 规范的一部分,用于对请求和响应进行底层处理,而 Interceptor 是 Spring 框架提供的用于增强 Controller 功能的机制。Filter 的执行优先于 Interceptor

防止请求存在缓存

防止请求存在缓存的策略对于保证数据的实时性和避免旧数据的获取非常重要。
解决方法,请求参数加一个时间戳,当然其他方法自己百度啦

function getData() {http.get(baseUrl + "/get?timestamp=" + new Date().getTime(), {headers: {'Authorization': token}}).then(response => {data.value = response.data;}).catch(error => {console.log(error);})
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com