跨域问题及解决

跨域问题

一、什么是 跨域?

当请求url协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。以下都属于跨域:

当前页面url被请求页面url原因
http://www.test.com/https://www.test.com/index.html协议不同(http/https
http://www.test.com/http://www.baidu.com/主域名不同(test/baidu
http://www.test.com/http://blog.test.com/子域名不同(www/blog
http://www.test.com:8080/http://www.test.com:7001/端口号不同(8080/7001

注意:协议、域名和端口都相同,但是请求路径不同,不属于跨域,如:www.jd.com/itemwww.jd.com/goods

二、什么是 跨域问题?

跨域问题是指一个页面尝试加载来自跨域(协议、域名、端口)的资源时所遇到的限制和问题。

在这里插入图片描述

如上图所示,由 http://localhost:8082 向 http://localhost:8088/user/list 发起 AJAX 请求,由于端口不同,产生了跨域问题。

三、为什么有 跨域问题?

为了保证浏览器的安全,不同源的客户端在没有明确授权的情况下,不能读写对方资源,称为同源策略

同源策略 是浏览器安全的基石。

四、什么是 同源策略?

同源策略(Same-Origin Policy)是一种Web安全机制,它定义了浏览器在加载网页时如何限制不同源之间的交互。

所谓同源(即指在同一个域)就是两个页面具有相同的协议(Protocol),主机(Host)和端口号(Port)

具体来说,同源策略限制了以下内容:

  1. JavaScript 访问:一个源的 JS代码 只能访问同源的资源,无法直接访问其他源的资源。

    这意味着,一个网页的 JS代码 无法读取/修改其他源的页面内容,包括 Cookie、LocalStorage、SessionStorage 等。

  2. DOM 访问:一个网页只能访问同源的DOM(文档对象模型)结构,无法直接访问其他源的DOM。

    这意味着,一个网页无法通过 JS代码 操作其他源的DOM,比如向其他源的表单提交数据 或 点击其他源的按钮。

  3. AJAX 请求:由于同源策略的限制,JS代码 不能直接通过 XMLHttpRequest对象 向其他源发起 AJAX请求。

    这意味着,一个网页无法通过 AJAX请求 获取其他源的数据,除非其他源明确允许跨域请求(通过CORS等方式)。

因此,跨域不一定有跨域问题,跨域问题是违反了同源策略的限制而产生的。(一般是AJAX请求获取跨域数据导致的)

五、为什么需要 同源策略?

同源策略的存在是为了保护用户的隐私和安全,防止恶意网站通过 JS代码 获取用户的敏感信息或者进行CSRF(跨站请求伪造)攻击。

可以说 同源策略 是浏览器安全的基石。

但同时 同源策略也带来了一些限制,需要开发者在设计网站时考虑如何合理地处理跨域访问的问题。

六、怎么解决 跨域问题?

1、CORS 简介

CORS(Cross-Origin Resource Sharing)跨域资源共享,是由W3C制定的一种跨域资源共享技术标准。

CORS 可以在不破坏即有规则的情况下,通过 浏览器 与 服务器 之间的交互, 实现跨域通信。

  1. 浏览器 发起 AJAX请求 时,在 请求头 携带请求的信息,以此来询问 服务端 是否允许当前网站的跨域请求。
  2. 服务端 接收到 浏览器 的请求后,会对请求信息做出判断,如果允许,就在 响应头 中携带一些许可的声明
  3. 浏览器 根据 服务端 的响应做出 拦截 或 放行 的处理。

这样,CORS 允许 浏览器 向 跨源服务器 发出 XMLHttpRequest 请求,从而克服了AJAX只能 同源 使用的限制。

2、CORS 请求分类

CORS 将请求分为两类:简单请求非简单请求,分别对跨域通信提供了支持。

满足以下条件的请求,即为 简单请求:

  • 请求方法:GET、POST、HEAD
  • 请求头:Accept、Accept-Language、Content-Language、Last-Event-ID、Content-Type
  • Content-Type:text/plain、multipart/form-data、application/x-www-form-urlencoded

如果不满足以上条件,即为 非简单请求。

3、简单请求

对于简单请求,CORS的策略是请求时在请求头中增加一个 Origin 字段

在这里插入图片描述

服务器收到请求后,判断该源是否允许跨域,如果允许,则在响应头中添加 Access-Control-Allow-Origin 字段

在这里插入图片描述

4、非简单请求

对于非简单请求的跨源请求,浏览器会在真实请求发出前增加一次 OPTION 请求,称为预检请求(pre flight request)

在这里插入图片描述

  • Origin:源信息
  • Access-Control-Request-Method:表示 请求方式
  • Access-Control-Request-Headers:包含 简单请求 以外的请求头信息。

服务器收到请求时,需要对 Origin、Access-Control-Request-Method、Access-Control-Request-Headers 等进行验证

验证通过后,会在响应头中添加相关信息:

在这里插入图片描述

  • Access-Control-Allow-Origin:允许哪些网站的跨域请求
  • Access-Control-Allow-Methods:允许跨域的请求方式
  • Access-Control-Allow-Headers:允许在请求中携带的头信息
  • Access-Control-Allow-Credentials:是否允许用户发送、处理cookie
  • Access-Control-Max-Age:预检请求的有效期,单位为秒,有效期内不会重复发送预检请求。

当预检请求通过后,浏览器才会发送真实请求到服务器。这样就实现了跨域资源的请求访问。

七、SpringBoot 解决跨域问题

1、局部配置

@CrossOrigin 注解加载对应的 Controller 上,这样对应的 Controller 中的所有方法都允许跨域

@CrossOrigin
@RestController
public class UserController {
    // ...
}

2、全局配置

使用配置类,对所有控制器生效

/**
 * Cors解决跨域问题
 */
@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
            .allowedOrigins("*")
            .allowedMethods("GET", "POST", "Options", "DELETE", "PUT")
            .allowedHeaders("*")
            .allowCredentials(true)
            .maxAge(16800);
    }
}

八、SpringCloud 解决跨域问题

在 SpringCloud Gateway 中,已经提供了默认的CORS实现,我们只需要通过 application.yml 做简单配置即可。

spring:
  cloud:
    gateway:
      # 全局的跨域处理
      globalcors: 
      	# 是否将当前cors配置加入到SimpleUrlHandlerMapping中,解决options请求被拦截问题
        add-to-simple-url-handler-mapping: true 
        # cors配置
        cors-configurations:
        # 拦截所有
          '[/**]':
            allowedOrigins: 			# 允许哪些网站的跨域请求(尽量使用域名)
              - "http://www.taobao.com"
              - "http://www.baidu.com"
            allowedMethods: 			# 允许的的请求方式(*表示全部)
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" 		# 允许在请求中携带的头信息(*表示全部)
            allowCredentials: true 		# 是否允许携带cookie
            maxAge: 360000 				# 跨域检测的有效期
  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scj1022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值