关于处理前后端分离项目的跨域问题

文章目录

  • 一、什么是跨域?
  • 二、为什么会发生跨域问题?
  • 三、在前后端分离项目中如何解决跨域
    • 1.跨域资源共享(CORS)
      • 方案1:在控制层的方法或类上加上@CrossOrigin注解
      • 方案2:使用全局配置cors
      • 方案3:注册CorsFilter组件
    • 2.nodejs中间件代理


一、什么是跨域?

当一个请求url的 协议域名端口 三者之间任意一个与当前页面url不同即为跨域。
例如:当前页面为http:127.0.0.1:8080
当发生如下请求时,代表发生跨域

请求地址 原因
https://127.0.0.1:8080 协议不同
http://192.168.0.1:8080 域名不同
http://127.0.0.1:80 端口不同

二、为什么会发生跨域问题?

出于浏览器的同源策略限制。同源策略(Sameoriginpolicy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。同源策略会阻止一个域的。javascript脚本和另外一个域的内容进行交互。所谓同源(即指在同一个域)就是两个页面具有相同的协议(protocol),主机(host)和端口号(port)。

三、在前后端分离项目中如何解决跨域

在前后端分离项目中,前端和后端的端口号往往会不同,导致发生跨域问题。目前我所知可以使用以下方案来进行处理。

1.跨域资源共享(CORS)

浏览器将CORS分成两类:简单请求非简单请求

  • 非简单请求包括putdelete以及请求头中Content-Type=application/json的请求
  • 简单响应请求这里偷个懒,记住除了非简单请求外的请求是简单请求
    其中非简单请求比简单请求多了一步:
    在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。浏览器先询问服务器,当前网页所在的域名是否在服务器的许可名单之中,以及可以使用哪些HTTP动词和头信息字段。只有得到肯定答复,浏览器才会发出正式的XMLHttpRequest请求,否则就报错。

对于简单请求,浏览器直接发出CORS请求。具体来说,就是在Header中增加一个Origin字段。如果浏览器发现跨源AJAX请求是简单请求,就自动在头信息之中,添加一个Origin字段。服务器根据Origin的值决定是否同意这次请求。如果同意,则会在响应头中加上一个属性Access-Control-Allow-Origin

下面是实现springboot中实现CORS的几种方式:

方案1:在控制层的方法或类上加上@CrossOrigin注解

@RestController
//value属性表示接收的当前请求地址,不写表示接收所有地址
//allowCredentials=true表示接收前端传来的cookie
@CrossOrigin(value = "http://localhost:7070",allowCredentials = "true")
public class AxiosController {
}

这样做的话,每一个控制类上都要加上这个注解,比较麻烦,不推荐

方案2:使用全局配置cors

@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                //*表示匹配所有
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .maxAge(3600)
                .allowCredentials(true);
    }
}

方案3:注册CorsFilter组件

@Configuration
public class CorsConfig {

    @Bean
    public CorsFilter corsFilter(){
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        //允许什么地址进行跨域请求
        corsConfiguration.addAllowedOrigin("http://localhost:8888");
        //允许携带cookie
        corsConfiguration.setAllowCredentials(true);
        //允许访问哪些方法
        corsConfiguration.addAllowedMethod("*");
        //允许携带哪些请求头
        corsConfiguration.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource urlBasedCorsConfigurationSource = new UrlBasedCorsConfigurationSource();
		//对当前项目下的哪些请求进行cors处理
        urlBasedCorsConfigurationSource.registerCorsConfiguration("/**",corsConfiguration);
        return new CorsFilter(urlBasedCorsConfigurationSource);
    }
}

2.nodejs中间件代理

当我们的后端没有配置CORS时,可以在前端中使用代理服务器来解决跨域问题
关于处理前后端分离项目的跨域问题_第1张图片
由客户端请求代理服务器,再由代理服务器请求目标服务器,目标服务器将数据返回代理服务器,代理服务器再将数据返回客户端。
如果是Vue项目,可以在项目的vue.config.js添加如下配置来处理

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  devServer:{
    port:7070,
    proxy: {
      '/api': {
      	//要代理到的服务器,可以是域名也可以是ip+端口号;
        target: 'http://localhost:8080',
        //虚拟托管网站,如果为true,源服务器获取的req.header的信息就是他自己的header,如果为false 那么获取的header信息就是代理服务器的
        changeOrigin: true,
      },
    },
  }
})

你可能感兴趣的:(springboot,springboot)