当前位置:网站首页 > 技术博客 > 正文

spring 跨域问题



如果你从事 web 应用开发,在前端使用异步请求(/)时,那你或多或少都应该在浏览器控制台见识过如下异常信息。

是的,这就是在异步请求时跨域失败的异常信息。接下来本文将会先简单地介绍跨域的基础知识,再详细地介绍如何在 spring 应用中处理跨域。

跨域,全称为“跨域资源共享”(Cross-origin resource sharing),是浏览器的一种安全机制。只会在浏览器中,使用 AJAX (fetch/XMLHttpRequest)时发生。当你在一个 web 页面中,使用 ajax 对目标 URL 发起了请求,只要目标 URL 的 协议主机端口 和当前 web 页面的 协议主机端口 任意不一致,就会产生跨域。

例如,我在页面 中,对如下 URL 发起 AJAX 请求,都会导致跨域:

当浏览器发现当前请求存在跨域的时候,浏览器会先往目标 URL 发送一个预检请求()进行预检。这个请求会提交一些 Header 信息,服务器会根据此做出响应,同样也会写入一些 Header。浏览器就可以根据响应的 Header 信息来确认是否要阻止当前的跨域请求,也就是跨域成功与否。

理解跨域,本质上就是理解和跨域有关的请求 Header 和 响应 Header。

  • 跨域请求,是从哪里发出,也就是表示请求来自哪个源(协议 + 主机 + 端口)。

  • 跨域请求将会使用什么请求方法发起请求。

  • 跨域请求将会提交哪些 Header 给服务器。

  • 允许发起跨域请求的源,例如:,可以使用通配符: 表示允许所有。

  • 允许跨域请求使用哪些请求方法,多个用逗号分割。

  • 允许跨域请求提交哪些 Header,多个用逗号分割。

  • 允许在跨域请求的响应中访问的额外的 Header 名称,多个的话,使用逗号分割。

    默认情况下,在跨域请求的响应中,Javascript 的的只能访问 、、、、、 这个几个基本的响应头。如果你要访问其他的 Header,需要通过此设置。例如:。

  • 缓存时间,可选,用来指定本次预检请求的有效期,单位为秒。在这个时间内,再次发起跨域请求不会再进行预检。

  • 是否允许客户端携带凭证,boolean 值。如果设置为 ,那么客户端在发起跨域请求的时候会在请求中携带 Cookie 等凭证信息。

用通俗的语言来描述跨域预检的过程:浏览器发现 Javascript 正在发起一个跨域请求的时候,会先往这个URL发起一个预检()请求,告诉服务器“我打算给你发起一个请求,我所在的地址是 XXX,我要使用 XXX 请求方法,我还要提交 XXX 等 Header”。服务器收到后请求后,响应服务器“我只接受来自于 XXX 的跨域请求,只能用 XXX 请求方法,请求只能携带 XXX Header,请求可以携带凭证,还允许客户端读取响应的 XXX Header,并且30分钟内不必重复发起预检请求”

完成了这一轮协商后,浏览器就可以判断是否要继续发起真正的跨域请求。

一些要注意的点:

  1. 如果服务器要求客户端可以携带凭证 ,那么 不能设置为通配符 ,而是必须要设置完整的跨域请求源。
  2. 、、 都可以设置通配符 ,但是可能存在浏览器兼容问题,需要注意。

进阶阅读:

  • MDN 官方对跨域的介绍
  • 阮一峰老师对跨域的介绍

简单一点,可以通过覆写 中的 方法来配置应用的全局的跨域设置。

是全局配置,如果你需要更精准的控制 Api 的跨域策略,可以通过在 handler 方法或者是 controller 类上注解 来设置。

有了前面的理论支撑,你也不难看出这些注解属性所代表的含义,它可以注解在 Controller 类上,对当前类中的所有 hanlder 方法都生效,也可以注解在 handler 方法上,仅对此方法生效。如下:

不管是 配置还是 注解,都是用硬编码方式配置跨域,这相当的不够灵活。

Spring 提供了一个 的 实现类,可以让我们更加灵活地,以编程式的方式来配置跨域。这也是我较为推荐的一种方式。

上面的这个 是一个万能 Filter,基本上可以解决 spring 应用中 999.999% 的跨域问题。

注意:不论任何方式,如果将 设置为了 ,则 必须设置明确的源,不能使用通配符: ,否则运行时会抛出异常:

另外,上述三种方式,任选其一就行。不要重复定义!

创建一个简单的 spring boot(3.x)项目,在 端口的 端点提供一个 HTTP 服务,固定响应字符串:。

打开浏览器,访问 ,看到的是一个 404 错误页面,这是因为没有设置默认主页,这没关系。

我们可以在控制台用 Javascript 代码发起跨域请求,把服务器的响应输出到控制台。

Spring 应用中的 CORS 请求

如你所见,成功读取到了服务器的响应,跨域配置生效。

以前可以直接在浏览器控制台看到 请求,不知道从什么时候起,Chrome 不再在控制台展示 CORS 相关的 OPTIONS 预检请求。

那就用 工具模拟一个 请求吧,下面就是预检的请求/响应日志。

  • 上一篇: securecrt 中文版
  • 下一篇: 测试流程规范
  • 版权声明


    相关文章:

  • securecrt 中文版2025-01-05 20:01:03
  • c语言函数指针和指针函数2025-01-05 20:01:03
  • java字符串初始化的几种方式2025-01-05 20:01:03
  • 归并排序算法python2025-01-05 20:01:03
  • webhook作用2025-01-05 20:01:03
  • 测试流程规范2025-01-05 20:01:03
  • sql简单编程2025-01-05 20:01:03
  • js 数组对象去重2025-01-05 20:01:03
  • 常用的jstl标签有哪些2025-01-05 20:01:03
  • openvswitch命令2025-01-05 20:01:03