SpringBoot+Vue的跨域问题

目录

一、跨域是如何产生的?

二、跨域产生的场景

三、跨域的前置知识

        1. 简单请求

        2. 非简单请求

四、如何解决跨域问题

        1.前端Vue项目可以配置代理(Proxy)

        2.后端SpringBoot项目配置CORS跨域策略

五、情况分析

六、总结


一、跨域是如何产生的?

        跨域问题产生的原因主要是浏览器的同源策略(Same-Origin Policy)。同源策略是一种安全机制,用于防止不同来源的网页之间的恶意操作。

源由协议(protocol)、主机(host)和端口(port)组成。即使是小的差异也会被视为不同的源:

  • 协议: HTTP 和 HTTPS 被视为不同的协议。
  • 主机: example.com 和 api.example.com 是不同的主机。
  • 端口: example.com:80 和 example.com:8080 是不同的端口。

只要有一个不同,那么就产生了跨域!

二、跨域产生的场景

        Vue项目运行在 http://127.0.0.1:80 上,SpringBoot项目运行在 http://127.0.0.1:8080 上,我们的Vue项目需要发起请求到SpringBoot上获取资源,假设发起请求的URL为:http://127.0.0.1:8080/user/list,因为发起请求的端口与Vue项目运行的端口不一致的原因,浏览器会受到同源策略的限制,阻止这种请求,此时就会遇到跨域问题

三、跨域的前置知识
        1. 简单请求

         GET 或 POST 方法,且不包含特殊的请求头部(除了 AcceptAccept-LanguageContent-Language 和 Content-Type 的特定值,其他都为特殊的请求头),则浏览器会直接发送请求,不会进行预检请求。

注:Content-Type 头部的简单值包括:

  • application/x-www-form-urlencoded
  • multipart/form-data
  • text/plain
        2. 非简单请求

        使用了 PUTDELETE 方法或带有自定义请求头部,浏览器会先发送一个预检请求(OPTIONS 请求)来确认服务器是否允许实际的跨域请求。

注:预检请求是请求方法为 “OPTIONS” 的请求,只有预检请求通过了,浏览器才会把实际的请求发送到后端。

四、如何解决跨域问题
        1.前端Vue项目可以配置代理(Proxy)

        在项目的根路径下的 vue.config.js 添加如下配置

module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: `http://127.0.0.1:8080`,
                changeOrigin: true,
                pathRewrite: { '^/api': '' }
            }
        }
    }
}

 这样,所有以 /api 开头的请求会被代理到 http://127.0.0.1:8080

各位会不会有这样的疑问,为什么配置代理就可以绕过浏览器的跨域问题?

  • 统一源: 代理服务器和前端应用通常运行在同一个源下,浏览器对同源策略的限制不再适用,因为所有的请求都首先被发送到代理服务器,而不是直接发送到目标服务器。

  • 转发请求: 代理服务器负责将请求转发到目标服务器并将响应返回给客户端。浏览器与代理服务器之间的通信是同源的,所以不受同源策略的限制。

注:前端应用中的代理配置通常仅用于开发环境。在生产环境中,前端应用直接与服务器通信,通常不再使用代理。

        2.后端SpringBoot项目配置CORS跨域策略

        在一个配置文件下注册CORS这个bean即可

@Configuration
public class GlobalCorsConfig {
    @Bean
    public CorsFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        //允许所有域名进行跨域调用
        config.addAllowedOriginPattern("*");
        //允许跨域发送cookie
        config.setAllowCredentials(true);
        //放行全部原始头信息
        config.addAllowedHeader("*");
        //允许所有请求方法跨域调用
        config.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsFilter(source);
    }
}

不知道大家有没有跟我一样的疑问,跨域是浏览器的同源策略问题,前端配置了代理就能绕过跨域,为什么后端还要配置CORS策略?

  • 生产环境的需要。代理不是全局解决方案,前端代理解决的是开发过程中跨域的问题。在生产环境中,服务器需要自行处理跨域请求,以确保应用能够正常运作。
  • 处理复杂场景。CORS 允许处理复杂的跨域场景,如预检请求(使用了非简单头部或方法的请求)。CORS 策略允许服务器响应这些预检请求并确定是否允许实际请求。

  • 确保安全性 配置 CORS 策略可以防止恶意网站通过脚本发送请求,从而对服务器施加攻击或滥用资源。只有经过授权的域名才能访问服务器的资源,这有助于防止潜在的安全漏洞。

  • 支持跨域请求。浏览器的同源策略限制了客户端(浏览器)直接访问不同源的资源。如果服务器没有配置 CORS 策略,即使前端应用试图通过浏览器发起跨域请求,浏览器也会阻止这些请求,导致应用无法正常工作。【这里一会重点说一下(情况分析)】

五、情况分析

        在触发了跨域问题的前提下,服务器没有配置 CORS 策略,如果浏览器发起请求(以一个简单请求和非简单请求为例),此时是怎样处理的呢?

简单请求前端没有配置代理。发起一个简单请求到后端,后端能够接收到请求并进行处理,即使前端没有配置代理,后端没有配置 CORS,后端还是可以正常处理请求并生成响应,浏览器会收到后端的响应,【但由于没有适当的 CORS 头部(Access-Control-Allow-Origin),前端应用无法访问响应的内容,具体表现为前端应用中的 JavaScript 代码无法读取响应数据,通常会触发一个跨域错误(No 'Access-Control-Allow-Origin' header is present on the requested resource.)】(浏览器同源策略的具体表现);前端配置了代理。那么可以正常解析响应请求,由于请求是从同源的代理服务器发起的,所以浏览器的同源策略不会阻止这个请求。

非简单请求:对于非简单请求,前端配不配置代理,都会发送一个预检请求(OPTIONS),来检查是否允许跨域请求,而后端没有配置CORS跨域策略(配置了会返回适当的 CORS 头部,如 Access-Control-Allow-Methods 和 Access-Control-Allow-Headers),所以这个预检请求不通过,那么实际请求也就不会发起。

六、总结

        后端服务器配置了CORS跨域策略,即可一劳永逸,前端无需配置跨域。因为对于简单请求来说,浏览器的同源策略,实际上是解析请求响应头上的Access-Control-Allow-Origin是否是当前域名能访问的(*代表任何域名都可以访问);而对于非简单请求,因为配置了CORS跨域策略,预检请求通过,实际的请求发起,后端在响应时设置了 Access-Control-Allow-Origin浏览器会允许前端应用访问响应数据。

  • 11
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值