一、情况简介

在学习spring boot+vue3前后端分离项目时,前期一直是用的自己电脑进行的开发及运行测试。当时就出现了跨域的问题,经过上网查询后在VUE中进行代理跨域的设置即可。但当我把前后端项目打包放到云服务上后却又出现了跨域的问题,经过大半天的查阅资料,终于解决了,以此记录。

1.跨域产生的情况

当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域。
如:
端口号不同
127.0.0.1:80 与 127.0.0.1:8888 属于跨域
域名 (或 ip 地址) 不同
127.0.0.1:80 与 www.baidu.com:80 属于跨域

2.前后端分离出现的跨域情况

例如:
前端 vue项目: 127.0.0.1:70
后端 SpringBoot项目: 127.0.0.1:8888
我们在前端 vue 项目中存放页面,页面中的数据是通过 axios 发起异步请求从 后端 SpringBoot项目中获取的。

因此当我们访问前端页面时候, 我们可以理解为当前所在 127.0.0.1:70 域上,所以访问这个127.0.0.1:70 域 的资源都是OK的,但如果使用 js 的方法访问其他域的资源时 就会出现跨域问题。
参考链接及处理方式:

二、跨域处理方式

1.后端处理

1).在每个 Controller 类上加入 @CrossOrigin 注解

@CrossOrigin 注解解决方案的优缺点:
优点 :
使用起来简单,直接在Controller类上加 @CrossOrigin 注解即可
缺点:
如果后端技术使用的不是 SpringBoot,后端代码还需要处理跨域问题
浏览器直接访问 后端API,在某种程度上是不太安全的

2).配置(SpringBoot)

@SpringBootConfiguration
public class MyWebConfigurer implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowCredentials(true)
                .allowedOriginPatterns("*")//允许所有域名
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .allowedHeaders("*");
    }
}

配置类文件一定要写在启动类所在的包下,否则不生效。

3).注意

两种方法不能同时使用,否则会报错。

2.前端处理(仅开发环境使用)

通过vue中的代理来处理。在vite.config配置中进行设置。
vue 中的 proxy 是利用 Node 代理

server: {
      // 服务器主机名,如果允许外部访问,可设置为 "0.0.0.0" 也可设置成外网的ip地址
      host: '0.0.0.0',
      port: 8080,
      open: true,
      https: false,
      cors: true,
      // 代理跨域
      proxy: {
        "/api": {
          target: "http://127.0.0.1:8443", 
          changeOrigin: true,
          rewrite: path => path.replace(/^\/api/, "") 
        }
      }
    },

在proxy中,/api:相当于请求时,遇见 /api 才进行代理。
target:表示转发地址(跨域的域名),这里设置的地址会代替axios中设置的baseURL
rewrite:因为真实的请求中没有/api,所以在rewrite中把 /api 去掉, 这样既有了标识, 又能在请求接口中把 /api 去掉。

理解

接口地址:http://127.0.0.1:88443/newList

// 请求接口:http://127.0.0.1:88443/api/newList
// axios请求
axios({
    method: 'get',
    url: '/api/newList'
}).then(res=>{})
// 上面请求接口可以分解为 127.0.0.1:8080    /api/newList

// 方法1 理解
// 当拦截到以/api开头路径时,把设置的跨域域名与路径拼接就变为了 http:127.0.0.1:3000/api/newList

1、假设你要调取的接口是http://127.0.0.1:8443/newList,然后你可以在本地调127.0.0.1:8080/api/newList,如axios.get(‘/api/newList’)
配置代理后,会做如下转发:
127.0.0.1:8080/api/newList -> http://127.0.0.1:8443/newList

3.部署nginx后的处理方式

系统上线后,由于前端vue打包后都会成为html和对应的js文件。要想独立部署又要解决跨域问题,就需要配置web容器的设置。因此需要修改nginx中的配置文件。

1).编辑配置文件

注意:应以自己安装nginx的文件路径为准,下面是示例

vim /usr/local/nginx/conf/nginx.conf

2).外网访问及代理配置

在server中

server {
        listen       8080;#对外访问的端口号
        server_name  XXX.XXX.XXX.XXX; #对外访问的地址
        location / {
            root   /www/html; #访问的路径
            index  index.html index.htm;
        }
        location ^~ /api{ #代理的配置
            add_header Access-Control-Allow-Origin *;
                add_header Access-Control-Methods 'GET,POST,OPTIONS' ;
            add_header Access-Control-Allow-Credentials true;
           proxy_set_header X-NginX-Proxy true;
           rewrite ^/api/(.*) /$1; break;
            proxy_pass http://xx.xx.xx.xx:xx; #代理后端的接口地址**
           index index.html index.htm;
        }
    }

总结

在处理跨域的问题时,自己因为也是新手,对这些问题的了解不够深入。只能通过网上到处查资料,并依次尝试。在尝试过程中,我把网上所说的几种方式都试了,但仍然没调通。后面决定先把后端调好后再解决前端。步骤为:

  1. 配置(SpringBoot),并自己调用接口,后端调通,不再出现跨域。
  2. 按照部署nginx后的处理方式进行处理,系统调通。