vue项目中,配置多个接口请求基准路径url地址

vue项目中,配置多个接口请求基准路径url地址

【需求】——一个前端项目需要搭配两个服务端接口

一、解决方案

1.1 描述接口context-path

后端的两个接口服务请求前缀,如下:

前缀1: /mini-rest
前缀2: /
1.2 vue.config.js配置
devServer: {
  port: 8005,
  proxy: {
    // 第一台服务器配置 
    '/mini-rest': {
      target: 'http://localhost:8085',
      ws: true,
      changeOrigin: true,
      pathRewrite: {
        '^/mini-rest': '/mini-rest'
      }
    },
    // 第二台服务器配置 
    '/': {
      target: 'http://localhost:8899',
      ws: true,
      changeOrigin: true,
      pathRewrite: {
        '^/': '/'
      }
    } 
  }
}
1.3 axios修改
// api base_url,设置前缀不存在
const BASE_URL = ''
// 创建 axios 实例
const service = axios.create({
 baseURL: BASE_URL, 
 timeout: 6000 // 请求超时时间
})

此时axios不需要直接指定baseUrl配置

1.4 发送请求
// 请求前缀为“/”
dibootApi.get("/trans").then(res => {
 console.log('/', res)
}).catch(err => {
 console.log(err)
})
// 请求前缀为“mini-rest”
dibootApi.get("/mini-rest/getTest").then(res => {
 console.log('/mini-rest', res)
}).catch(err => {
 console.log(err)
})

注:请求的时候手动加上前缀

1.5 结果展示

在这里插入图片描述

总结

多个接口服务的情况下,如果前缀是"/",要将其放在proxy配置的最后一部分,代理的时候是从上往下查找的,如果放在最上面其他服务也会被该配置代理掉

二、实例

1、src/api/index.js
// 配置项目的axios,导出进行全局配置

// 基准地址
// axios.defaults.baseURL =
//     'http://10.88.155.43/tkweb-legal-platform/lumen/public/rest/'
import Vue from 'vue'
import axios from 'axios'
import qs from 'qs'
import store from '@/store'
import router from '../router'
const config = {
  // baseURL在此处省略配置,考虑到项目可能由多人协作完成开发,域名也各不相同,此处通过对api的抽离,域名单独配置在base.js中

  // 请求超时时间
  timeout: 60 * 1000,
  //————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

  // baseURL: 'http://10.88.155.43/takweb-legal-platform/lumen/public/rest/',
  //本地验证接口时用
  baseURL: '/api/',
  //开发机验证接口时用
  // baseURL: '/rest/',
  //————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

  // 跨域请求时是否需要凭证
  // withCredentials: true, // Check cross-site Access-Control
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8',
    'Access-Control-Allow-Origin': '*'
  }
}

// 创建实例
const _axios = axios.create(config)
// 请求拦截器
_axios.interceptors.request.use(
  function (config) {
    // 从vuex里获取token
    // const token = store.state.token
    //     // 如果token存在就在请求头里添加
    // token && (config.headers.token = token)
    return config
  },
  function (error) {
    // // Do something with request error
    // error.data = {}
    // error.data.msg = '服务器异常'
    return Promise.reject(error)
  }
)

// 响应拦截器
_axios.interceptors.response.use(
  function (response) {
    // 清除本地存储中的token,如果需要刷新token,在这里通过旧的token跟服务器换新token,将新的token设置的vuex中
    //console.log('haha', repsonse)
    //if(response.data.code===401){
    //    localStorage.removeItem("token");
    //delete storage.token;
    //}
    // 只返回response中的data数据
    return response.data
  },
  function (error) {
    if (error) {
      // 请求已发出,但不在2xx范围内
      //  errorHandle(error.status,error.data.msg);
      if (error.response.status == '401') {
        if (store.getters['auth/isLoggedIn']) {
          delete localStorage.token;
          store.dispatch('auth/login_status_change');
        } else {
          store.dispatch('auth/login_status_change');
        }
        router.currentRoute.path !== '/login' &&
          router.replace({
            path: '/login',
            query: {
              redirect: router.currentRoute.fullPath
            }
          });
        //store.dispatch('auth/gotoLogin');
      }
      return Promise.reject(error)
    } else {
      // 断网
      return Promise.reject(error)
    }
  }
)

/**
 * get 请求方法
 * @param url
 * @param data
 * @returns {Promise}
 */
const get = (url, data = {}) => {
  return new Promise((resolve, reject) => {
    _axios.get(url, {
      params: data
    }).then(
      response => {
        resolve(response)
      },
      err => {
        if (err.response.status == '401') {
          if (store.getters['auth/isLoggedIn']) {
            delete localStorage.token;
            store.dispatch('auth/login_status_change');
          } else {
            store.dispatch('auth/login_status_change');
          }
          router.currentRoute.path !== '/login' &&
            router.replace({
              path: '/login',
              query: {
                redirect: router.currentRoute.fullPath
              }
            });
        }
        /*| err.response.status == '405'
        if(err.response.status == 401){
            localStorage.removeItem("token");
        }

        if (store.getters['auth/isLoggedIn']) {
            store.dispatch('auth/logout');
            this.$router.push({path:'/login', query: {redirect:this.$route.fullPath}});
        }
        */
        reject(err)
      }
    )
  })
}

/**
 * post 请求方法
 * @param url
 * @param data
 * @returns {Promise}
 */
const post = (url, params) => {
  return new Promise((resolve, reject) => {
    _axios.post(url, qs.stringify(params))
      .then(
        response => {
          resolve(response)
        },
        err => {
          reject(err)
        }
      )
  })
}

//  DELETE 方法封装
//  export const deleteRequest = (url) => {
//    return axios({
//        method: 'delete',
//            url: url
//              });
//              }
const deleteRequest = (url) => {
  return new Promise((resolve, reject) => {
    _axios.delete(url)
      .then(
        response => {
          resolve(response)
        },
        err => {
          reject(err)
        }
      )
  })
}

/**
 * put 请求方法
 * @param url
 * @param data
 * @returns {Promise}
 */
const put = (url, params) => {
  return new Promise((resolve, reject) => {
    _axios.put(url, qs.stringify(params))
      .then(
        response => {
          resolve(response)
        },
        err => {
          reject(err)
        }
      )
  })
}

export default {
  get,
  post,
  deleteRequest,
  put
}
2、vue.config.js
// vue.config.js
module.exports = {
  //本地验证接口时用
  //————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————


  runtimeCompiler: true, //是否使用包含运行时编译器的Vue内核版本
  lintOnSave: false,
  //publicPath: '/dist/',
  //outputDir: './dist',
  transpileDependencies: [
    'vue-socket.io',
    'vue-echarts',
    'resize-detector',
  ],
  devServer: {
    open: true,
    // host: 'localhost',
    host: '0.0.0.0',
    port: 8080,
    hot: true,
    disableHostCheck: true,
    https: false,
    //以上的ip和端口是我们本机的;下面为需要跨域的
    proxy: {
      //配置跨域
      '/api': {
        // target: 'http://10.88.155.43/takweb-legal-platform/lumen/public/rest/', //真实数据:这里后台的地址模拟的;应该填写你们真实的后台接口1
        target: 'http://10.88.155.45:9910/rest/', //真实数据:这里后台的地址模拟的;应该填写你们真实的后台接口1
        // target: 'http://localhost:3000/rest/', //node模拟数据:这里后台的地址模拟的;应该填写你们真实的后台接口
        ws: true,
        changOrigin: true, //允许跨域
        pathRewrite: {
          '^/api': '' //请求的时候使用这个api就可以
        }
      }
    }
  }


  //————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

  //开发机验证接口时用
  //————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

  // lintOnSave: false,
  // runtimeCompiler: true, //是否使用包含运行时编译器的Vue内核版本
  // publicPath: '/dist/',
  // outputDir: './dist',
  // transpileDependencies: [
  //     'vue-socket.io',
  //     'vue-echarts',
  //     'resize-detector',
  // ],
  // devServer: {
  //   open: true,
  //   public: '0.0.0.0:8080',
  // // // //   //host: '0.0.0.0',
  // // // //   //port: 8080,
  //   hot: true,
  //   disableHostCheck: true,
  // // //   //https: false,
  // // // //   //以上的ip和端口是我们本机的;下面为需要跨域的

  // // // //   proxy: {
  // // // //     //配置跨域
  // // // //     '/api': {
  // // // //       target: 'http://10.88.155.43/takweb-legal-platform/lumen/public/rest/', //这里后台的地址模拟的;应该填写你们真实的后台接口
  // // // //       // target: 'http://localhost:3000/', //这里后台的地址模拟的;应该填写你们真实的后台接口
  // // // //       ws: true,
  // // // //       changOrigin: true, //允许跨域
  // // // //       pathRewrite: {
  // // // //         '^/api': '' //请求的时候使用这个api就可以
  // // // //       }
  // // // //     }
  // // // //   }
  // // // //   */
  // }
}
//————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————

//}
<think>好的,我现在需要帮助用户解决HTTP请求返回的net::ERR_ABORTED 404 Not Found错误。用户提到错误发生在localhost:8086,请求路径是assets/index-BBrXdR98.js。根据用户提供的引用内容,我需要综合这些信息来给出解决方案。 首先,我需要回忆常见的404错误原因。通常,404错误意味着服务器找不到请求的资源。可能的原因包括路径错误、资源未正确部署、缓存问题或服务器配置问题。根据用户提供的引用,有几个可能的解决方法: 1. **检查路径正确性**:用户需要确认请求URL路径是否与实际资源路径完全一致,包括大小写和特殊字符。例如,引用[2]提到即使路径看起来正确,也可能存在隐藏的问题,比如IDE的自动补全可能导致路径错误,但实际部署时路径不正确。 2. **清理缓存和强制刷新**:浏览器缓存可能导致旧路径被引用,即使资源已经更新。引用[2]和[5]建议使用Ctrl+F5强制刷新或清除浏览器缓存。此外,用户提到的临时解决方法,将文件复制到其他路径重新引入,可能涉及到缓存失效的问题,所以清理缓存很重要。 3. **静态资源配置问题**:如果使用框架如Vue,可能需要检查publicPath的设置。引用[3]和[5]提到将publicPath设置为"./"可以解决资源路径问题。需要确认vue.config.js中的配置是否正确,以及生产环境构建后的路径是否匹配服务器配置。 4. **服务器配置问题**:例如Nginx或Spring Boot的静态资源目录配置是否正确。引用[3]指出需要检查服务器配置,并重启服务。对于Spring Boot,可能需要将资源放在src/main/resources/static目录下,并确保配置类正确映射静态资源。 5. **依赖安装和引用路径**:引用[4]中提到,如果使用npm包,需要正确安装依赖并通过node_modules引用,而不是直接使用相对路径。用户可能需要检查是否所有依赖都已正确安装,并且构建过程中资源被正确打包。 6. **IDE或构建工具问题**:有时候IDE(如IntelliJ IDEA)可能显示路径正确,但实际运行时路径不同。引用[2]提到尝试移动文件位置或重启项目可能解决问题,这可能与IDE的缓存或热部署机制有关。 接下来需要将这些可能的解决方案分步骤整理,确保用户能逐步排查问题。同时,需要注意用户的具体情况:使用localhost:8086,资源路径为assets/index...js,这可能涉及前端框架的打包配置或后端服务器的静态资源处理。例如,如果是Vue项目,构建后的dist目录结构是否与服务器配置匹配;如果是Spring Boot,静态资源是否放置在正确的位置。 还需要考虑用户是否在构建后正确部署了资源。例如,是否运行了npm run build,并将生成的文件部署到服务器的正确位置。另外,可能需要检查文件名中的哈希值是否导致缓存问题,或者文件名在构建过程中被更改,但引用路径未更新。 最后,根据用户提供的引用中的解决方法,整理出结构清晰的步骤,涵盖路径检查、缓存清理、服务器配置、构建配置多个方面,确保用户能全面排查问题。</think>### 解决HTTP请求404错误的步骤指南 #### 1. **验证资源路径的正确性** - **检查请求URL与实际路径**:确认浏览器请求URL(如`http://localhost:8086/assets/index-BBrXdR98.js`)与文件实际存放路径**完全一致**,包括大小写、特殊字符和子目录层级。例如: - 如果资源存放在`src/main/resources/static/assets/`目录下,需确保服务器配置的静态资源路径包含此目录。 - **IDE的路径显示可能误导**:引用[2]提到IDE中可能显示路径正确,但运行时路径不同,需手动比对部署后的目录结构。 - **使用绝对路径替代相对路径**:若项目使用前端框架(如Vue),建议通过`publicPath`配置统一路径基准。例如在`vue.config.js`中设置: ```javascript module.exports = { publicPath: process.env.NODE_ENV === 'production' ? './' : '/' } ``` 引用[3][^3]和[5][^5]均指出此配置对资源加载的影响。 #### 2. **清理缓存与强制刷新** - **浏览器端操作**: - 按`Ctrl+Shift+Del`清除浏览器缓存(勾选“缓存的图像和文件”)。 - 使用`Ctrl+F5`强制刷新页面,忽略缓存。 - **服务端操作**: - 若使用Nginx,执行`nginx -s reload`重启服务。 - 若为Spring Boot项目,通过`mvn clean install`重新构建并重启应用。 #### 3. **检查服务器静态资源配置** - **后端框架配置示例**: - **Spring Boot**:确保资源文件位于`src/main/resources/static/`目录,或通过`WebMvcConfigurer`自定义映射: ```java @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/assets/**") .addResourceLocations("classpath:/static/assets/"); } } ``` - **Nginx**:检查`nginx.conf`中`location`块是否指向正确目录: ```nginx location /assets/ { alias /project/static/assets/; } ``` - **前端框架构建配置**: - 若使用Vue/React,构建后生成的`dist`目录需完整部署到服务器,并通过服务器配置指向该目录。 #### 4. **依赖管理与构建问题** - **安装缺失的依赖**:若资源通过npm包引入(如`template-web.js`),需确保执行`npm install art-template --save`,并引用`node_modules`中的文件(引用[4][^4])。 - **检查构建输出**: - 运行`npm run build`后,检查`dist/assets`目录下是否存在`index-BBrXdR98.js`。 - 若文件名包含哈希(如`index-BBrXdR98.js`),确认HTML中引用的哈希值与实际文件一致。 #### 5. **IDE与文件系统同步** - **强制刷新IDE缓存**:在IntelliJ IDEA中,右键点击资源目录选择`Reload from Disk`。 - **重启项目或服务器**:引用[2][^2]提到,临时移动文件位置后重启可能解决IDE缓存导致的路径错误。 #### 6. **网络请求分析** - **开发者工具排查**: 1. 打开浏览器开发者工具(F12),进入**Network**选项卡。 2. 查找失败的请求(状态码404),查看其**Headers**中的`Request URL`。 3. 对比实际文件路径与`Request URL`差异,修正路径配置。 #### 7. **扩展场景排查** - **代理或CDN干扰**:若使用反向代理或CDN,检查其缓存策略或重写规则是否拦截请求。 - **文件权限问题**:在Linux服务器中,通过`chmod -R 755 /static`确保资源目录可读。 --- ### 常见问题解答 - **Q: 路径正确但依然404,如何解决?** A: 尝试上述“临时文件替换法”(引用[2]),将文件复制到新路径后重新引入,触发IDE或服务器刷新路径映射。 - **Q: Vue项目部署后资源加载失败?** A: 优先检查`publicPath`配置是否为相对路径(`./`),并确保服务器根目录包含`dist`内容(引用[3][^3])。 --- ###
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值