Vue如何处理浏览器跨域问题

1. 什么是跨域

跨域 问题是由于浏览器 的同源策略(Same-Origin Policy)所导致的,

同源策略是浏览器的一种安全机制,

限制一个域的网页与另一个域的资源进行交互,

即限制了一个源(协议、域名、端口)下的文档或脚本与另一个源的资源进行交互,

也就是浏览器向不同源 (不用协议、不用域名、不同端口)发送ajax请求会失败。

2. 跨域的例子

比如,我们启动的项目,启动了两个服务:

  • 前端端口是5173
  • 后端端口是8080

当浏览器启动后,会先发送请求,到前端服务,比如得到一个登录页面

这个登录页面所在的源,就是http://localhost:5173

在登录页面里,嵌套了一段js代码,里面有一个登录按钮,

当用户点击登录按钮时,会发送请求到后端服务http://localhost:8080

此时ajax请求所在的源是5173,但它请求的目标是8080,

这个时候,属于不同的源,

由于浏览器的同源策略限制,该请求会发送失败,这种就是跨域问题。

3. 配置代理解决跨域问题

配置代理后,请求就不会从5173直接发向8080,

当点击登录按钮,发送异步请求时,会先把请求发向前端服务5173,

此时异步请求所在的源就是5173,所以就不会出现跨域问题,

再由前端服务5173,转发到后端服务8080,

也就是说,该请求是由服务端发起的,就没有跨域问题了。

4. 如何配置代理

  1. 首先在utils中的请求工具request.js里,把写固定的路径修改一下。

    示例代码如下:

    javascript 复制代码
    //这里边相当于请求的工具,用来定制请求的实例
    
    //导入axios npm install axios
    import axios from 'axios';
    
    //导入Message消息提示
    import { ElMessage } from 'element-plus';
    
    //定义一个变量,记录公共的前缀,baseURL
    // const baseURL = 'http://localhost:8080';
    // 这里的'/api'只是给后台访问的请求路径添加一个标识
    const baseURL = '/api';
    /*  axios.create()方法,把baseURL作为参数传入,
        该方法返回一个请求的实例instance,
        以后发送请求时,就不用axios.get了,
        直接用instance.get就可以 */
    const instance = axios.create({baseURL})
    
    /* axios提供的拦截器,
        在请求或响应,被then或catch处理前拦截
        也就是在请求发出之前,有一个请求拦截器
        或在响应到达之前,有一个响应拦截器 */
    
    //添加响应拦截器(这个拦截器本身就是异步的)
    instance.interceptors.response.use(
        //成功的回调
        result=>{
            //判断业务状态码
            if(result.data.code === 0){
                return result.data;
            }
            
            //操作失败
            ElMessage.error(result.data.msg?result.data.msg:'服务异常');
            
            //异步操作的状态转换为失败
            return Promise.reject(result.data);
        },
        //失败的回调
        err=>{
            alert('服务异常');
            
            //异步的状态转化成失败的状态
            return Promise.reject(err);
        }
    )
    
    //把请求的实例instance导出,供其他地方调用
    export default instance;

    上述代码中,只是把const baseURL = 'http://localhost:8080';

    改成了const baseURL = '/api';

    意思就是,比如以前写的 const baseURL = 'http://localhost:8080';

    现在改成 const baseURL = '/api';

    这里的 '/api' 其实就是是给后台访问的请求路径添加一个标识,

    然后在配置代理里,会把这个 '/api' 替换为我们想要的路径,

    api前边并没有写端口号,就会把当前ajax请求所在的源自动拼进去,

    就相当于写的http://localhost:5173/api,

    因为当前ajax代码所处的源,就是刚才页面所处的源http://localhost:5173

    所以当用户点击登录按钮时,请求就发送给5173的这个前端服务,

    两个源都是5173,所以不会出现跨域

  2. 在vite.config.js配置信息里边,添加 '/api' 的对应配置

    这里的配置,才是真正配置代理的,

    这里才是配置请求路径和端口号的地方。

    示例代码:

    javascript 复制代码
    //这里边写的是vue项目的配置信息,如端口号等
    
    import { fileURLToPath, URL } from 'node:url'
    
    import { defineConfig } from 'vite'
    import vue from '@vitejs/plugin-vue'
    import vueDevTools from 'vite-plugin-vue-devtools'
    
    // https://vite.dev/config/
    export default defineConfig({
      plugins: [
        vue(),
        vueDevTools(),
      ],
      resolve: {
        alias: {
          '@': fileURLToPath(new URL('./src', import.meta.url))
        },
      },
    
      //sercer:代表是要做服务相关的配置
      server: {
        //proxy: 指的是要配置一些代理
        proxy: {
          //这里的'/api'是指:请求路径中,是否有带/api这部分的路径,如果有/api,就对其进行处理
          '/api': { //获取路径中包含了/api的请求
            //target:指的是,如果要更换源,要更换成谁,就写谁,这里写的是后台服务所在的源
            target: 'http://localhost:8080',
    
            //changeOrigin:指的是,是否要更换换源
            changeOrigin: true,
    
            // rewrite:是路径的重写,这里把/api替换为''
            rewrite: (path) => path.replace(/^\/api/, '')
          }
        }
      }
    })

    为了更好的理解上边的配置,举个例子:

    比如发送异步请求,路径是http://localhost:5173/api/user/register,

    这个路径中,有 /api,配置信息里的 changeOrigin: true,就会更改源,

    把源改为target的 'http://localhost:8080',

    改完后就变成了http://localhost:8080/api/user/register,

    就是把 /api 前边的路径给换了,

    同时,rewrite重写路径,把 /api重写成空字符串

    最后,路径就是这样的http://localhost:8080/user/register。

以上就是Vue通过配置代理来解决跨域问题。

相关推荐
bin915320 分钟前
DeepSeek与Vue.js组件开发:解锁AI与前端开发的融合密码
vue.js·deepseek
禁默27 分钟前
【学术投稿-第六届新材料与清洁能源国际学术会议(ICAMCE 2025)】组织与结构:HTML中的<fieldset>与<legend>标签解析
前端·html
南城巷陌27 分钟前
Node.js的API之dgram的用法详解
前端·node.js·dgram
不会&编程28 分钟前
第3章 使用 Vue 脚手架
前端·javascript·vue.js
ttod_qzstudio31 分钟前
基于Typescript,使用Vite构建融合Vue.js的Babylon.js开发环境
vue.js·typescript·babylon.js
杨晓风-linda33 分钟前
Angular-hello world
前端·javascript·angular.js
一只理智恩33 分钟前
Cesium 离线加载瓦片图
前端·javascript·arcgis
115432031q1 小时前
基于SpringBoot养老院平台系统功能实现十一
java·前端·后端
AC-PEACE1 小时前
route 与 router 之间的差别
前端·网络
星空你好2 小时前
npm link,lerna,pnmp workspace区别
前端·npm·node.js