vue搭建脚手架之后vue.config.js配置和封装request.js

这段代码展示了在Vue.js应用中使用Axios库进行HTTP请求的配置,包括设置请求头、防重复提交机制、错误处理、响应拦截器以及一个通用的下载方法。此外,还配置了VueCLI的devServer代理以访问API。

request.js

import axios from 'axios'
import cache from '@/plugins/cache'
import errorCode from '@/util/errorCode'
import { tansParams, blobValidate } from "@/util/zhy";
import { Notification, MessageBox, Message, Loading } from 'element-ui'

let downloadLoadingInstance;
// 是否显示重新登录
export let isRelogin = { show: false };

axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
  // axios中请求配置有baseURL选项,表示请求URL公共部分
  // baseURL: 'http://192.168.x.xx:xxxx',
  // 超时
  timeout: 10000
})
// request拦截器
service.interceptors.request.use(config => {
  // 是否需要防止数据重复提交
  const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
  // get请求映射params参数
  if (config.method === 'get' && config.params) {
    let url = config.url + '?' + tansParams(config.params);
    url = url.slice(0, -1);
    config.params = {};
    config.url = url;
  }
  if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
    const requestObj = {
      url: config.url,
      data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
      time: new Date().getTime()
    }
    const sessionObj = cache.session.getJSON('sessionObj')
    if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
      cache.session.setJSON('sessionObj', requestObj)
    } else {
      const s_url = sessionObj.url;                  // 请求地址
      const s_data = sessionObj.data;                // 请求数据
      const s_time = sessionObj.time;                // 请求时间
      const interval = 1000;                         // 间隔时间(ms),小于此时间视为重复提交
      if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
        const message = '数据正在处理,请勿重复提交';
        console.warn(`[${s_url}]: ` + message)
        return Promise.reject(new Error(message))
      } else {
        cache.session.setJSON('sessionObj', requestObj)
      }
    }

  }
  return config
}, error => {
  Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
  // 未设置状态码则默认成功状态
  const code = res.data.code || 200;
  // 获取错误信息
  const msg = errorCode[code] || res.data.msg || errorCode['default']
  // 二进制数据则直接返回
  if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
    return res.data
  }
  if (code === 401) {
    if (!isRelogin.show) {
      isRelogin.show = true;
      MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
        isRelogin.show = false;
        store.dispatch('LogOut').then(() => {
          location.href = '/index';
        })
      }).catch(() => {
        isRelogin.show = false;
      });
    }
    return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
  } else if (code === 500) {
    Message({ message: msg, type: 'error' })
    return Promise.reject(new Error(msg))
  } else if (code === 601) {
    Message({ message: msg, type: 'warning' })
    return Promise.reject('error')
  } else if (code !== 200) {
    Notification.error({ title: msg })
    return Promise.reject('error')
  } else {
    return res.data
  }
},
  error => {
    console.log('err' + error)
    let { message } = error;
    if (message == "Network Error") {
      message = "后端接口连接异常";
    } else if (message.includes("timeout")) {
      message = "系统接口请求超时";
    } else if (message.includes("Request failed with status code")) {
      message = "系统接口" + message.substr(message.length - 3) + "异常";
    }
    Message({ message: message, type: 'error', duration: 5 * 1000 })
    return Promise.reject(error)
  }
)

// 通用下载方法
export function download(url, params, filename, config) {
  downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
  return service.post(url, params, {
    transformRequest: [(params) => { return tansParams(params) }],
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    responseType: 'blob',
    ...config
  }).then(async (data) => {
    const isLogin = await blobValidate(data);
    if (isLogin) {
      const blob = new Blob([data])
      saveAs(blob, filename)
    } else {
      const resText = await data.text();
      const rspObj = JSON.parse(resText);
      const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
      Message.error(errMsg);
    }
    downloadLoadingInstance.close();
  }).catch((r) => {
    console.error(r)
    Message.error('下载文件出现错误,请联系管理员!')
    downloadLoadingInstance.close();
  })
}

export default service

vue.config.js

const { defineConfig } = require('@vue/cli-service')
const path = require('path')
function resolve(dir) {
  return path.join(__dirname, dir)
}

module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
  devServer: {
    host: '0.0.0.0',
    port: 9401,
    proxy: {
      // detail: https://cli.vuejs.org/config/#devserver-proxy
      ['/api']: {
        target:`http://192.168.x.x:xxxx`, 
        changeOrigin: true,
        pathRewrite: {
          ['^' + '/api']: ''
        }
      },
  }
},
configureWebpack: {
  name: '',
  resolve: {
    alias: {
      '@': resolve('src')
    }
  }
},

})
<think>首先,用户的问题是关于Vue2Node.js前后端项目中封装axios的方法。我需要参考提供的引用内容,这些引用是关于Axios在Vue项目中的封装。 回顾引用: - 引用[1]: 描述了Axios的特点,如运行在浏览器Node.js、基于Promise、默认GET请求、自动转换JSON、拦截请求响应等。 - 引用[2]: 提到了Vue封装axios的方法,包括各种请求方式(get, post, put, delete等),以及在src下新建network文件夹的结构。 - 引用[3]: 讨论了在Vue项目中使用Axios进行前后端交互,包括使用vue-cli脚手架搭建项目。 用户的上一个问题似乎不是我直接看到的,但根据系统级指令,我需要参考用户上一次的问题我的回答。在这个对话中,用户的问题就是这个:"我想查找Vue2与Node.js前后端项目中封装axios的方法"。所以,我应该基于这个问题来回答。 系统指令要求: - 所有行内数学表达式使用$...$格式(但在这个上下文中应该没有数学表达式,因为主题是前端开发)。 - 独立公式使用$$...$$格式(同样,可能不需要)。 - LaTeX语法正确(但这里主要是文本,所以保持正确即可)。 - 使用中文回答。 - 生成相关问题(在回答末尾添加相关问题)。 - 回答中引用的段落末尾自然地添加引用标识,例如[^1]。 结构我的回答: 1. **介绍Axios封装的原因**:基于引用[1],解释Axios的特点为什么需要封装。 2. **封装方法**:基于引用[2],描述在Vue2项目中如何封装Axios,如在src下创建network文件夹,定义请求实例。 3. **结合Node.js后端**:用户提到了前后端项目,所以需要讨论后端部分。引用[3]提到了后端交互,但焦点在Vue前端。我应该补充Node.js后端如何与前端Axios交互。例如,在Node.js中使用Express或其他框架处理请求。 4. **步骤指南**:提供清晰的步骤,帮助用户实现封装。 5. **代码示例**:基于引用[2],给出一些代码片段。 6. **添加引用标识**:在引用内容末尾添加[^1], [^2], [^3]。 7. **生成相关问题**:在末尾添加几个相关问题。 确保回答真实可靠:基于我的知识引用内容。引用内容是关于Vue2Axios的,所以我可以扩展解释。 大纲回答: - 开头简述封装Axios的必要性。 - 在Vue2前端封装Axios: - 创建Axios实例。 - 设置拦截器(请求响应)。 - 定义API函数。 - Node.js后端部分:简要说明后端如何接收请求(使用Express),但不深挖,因为用户焦点在前端封装。 - 代码示例:给出一个简单的封装代码。 - 相关问题。 使用中文。 最终回答结构: 1. 解释Axios封装。 2. 描述前端封装步骤。 3. 集成后端。 4. 代码块。 5. 相关问题。 </think>### Vue2与Node.js前后端项目中封装Axios的方法 在Vue2Node.js前后端项目中,封装Axios可以提升代码的可维护性、复用性错误处理能力。Axios是一个基于Promise的HTTP客户端,支持在浏览器Node.js环境中运行,能自动转换JSON数据,并提供请求/响应拦截功能[^1]。封装Axios的核心在于创建一个统一的请求实例,配置默认参数、拦截器,以及封装API调用函数。下面我将一步步解释封装方法(包括前端Vue2后端Node.js的集成),并提供代码示例。整个过程基于Vue CLI搭建的项目结构。 #### 1. **项目准备与环境搭建** 在开始封装前,确保你的前后端项目已设置好: - **前端Vue2)**:使用Vue CLI创建项目(默认基于Webpack模板)。在终端运行以下命令: ```bash # 全局安装Vue CLI npm install -g vue-cli # 创建Vue2项目 vue init webpack my-project ``` 安装Axios依赖:在项目根目录运行 `npm install axios --save`[^3]。 - **后端(Node.js)**:使用Express框架搭建简单API服务器。安装Express:`npm install express`。例如,创建一个 `server.js` 文件: ```javascript const express = require('express'); const app = express(); app.use(express.json()); // 解析JSON请求体 // 示例API路由 app.get('/api/data', (req, res) => { res.json({ message: "后端数据成功返回" }); }); app.listen(3000, () => { console.log('Node.js后端服务器运行在 http://localhost:3000'); }); ``` 启动后端:`node server.js`。确保后端服务运行在端口3000(或其他端口),前端通过Axios与之通信。 #### 2. **在Vue2前端封装Axios** 封装的目的是统一处理请求配置、错误拦截API管理。参考前端最佳实践,在 `src` 目录下创建 `network` 文件夹存放网络请求模块[^2]。以下是详细步骤: - **步骤1: 创建Axios实例配置文件** 在 `src/network` 文件夹中,创建 `request.js` 文件。这里设置基础URL、超时时间、请求头等默认配置: ```javascript // src/network/request.js import axios from 'axios'; // 创建Axios实例,配置默认参数 const service = axios.create({ baseURL: 'http://localhost:3000/api', // 指向Node.js后端API地址 timeout: 5000, // 请求超时时间(毫秒) headers: { 'Content-Type': 'application/json' // 默认JSON格式 } }); // 请求拦截器:在发送请求前处理(例如添加Token) service.interceptors.request.use( config => { // 示例:从localStorage获取用户Token并添加到请求头 const token = localStorage.getItem('token'); if (token) { config.headers.Authorization = `Bearer ${token}`; } return config; }, error => { return Promise.reject(error); // 请求错误处理 } ); // 响应拦截器:处理后端返回的数据 service.interceptors.response.use( response => { // 如果响应状态码为200,直接返回数据部分 if (response.status === 200) { return response.data; } return Promise.reject(new Error('响应状态码异常')); }, error => { // 统一处理HTTP错误(如404或500) console.error('Axios响应错误:', error.response); return Promise.reject(error); } ); export default service; // 导出配置好的Axios实例 ``` - **步骤2: 封装API函数** 在 `src/network` 文件夹中,创建 `api.js` 文件,定义具体的API调用方法(如GET、POST)。这提高了代码复用性[^2]: ```javascript // src/network/api.js import request from './request.js'; // 封装GET请求示例 export const fetchData = () => { return request({ url: '/data', // 对应后端路由 /api/data method: 'get' }); }; // 封装POST请求示例 export const postData = (data) => { return request({ url: '/submit', method: 'post', data: data // 发送的数据会被自动转换为JSON格式 }); }; ``` - **步骤3: 在Vue组件中使用封装的API** 在Vue组件中导入并使用这些API函数。例如,在 `src/components/Example.vue` 中: ```vue <script> import { fetchData, postData } from '@/network/api'; export default { methods: { async getData() { try { const response = await fetchData(); console.log('获取数据成功:', response); } catch (error) { console.error('请求失败:', error); } }, async submitData() { const payload = { name: '示例' }; try { await postData(payload); console.log('数据提交成功'); } catch (error) { console.error('提交失败:', error); } } } }; </script> ``` #### 3. **Node.js后端与Axios的集成** 后端Node.js不需要封装Axios(因为Axios主要用于客户端),但需要处理来自前端的请求: - 在前端的 `request.js` 中,`baseURL` 指向Node.js服务的地址(如 `http://localhost:3000/api`)。 - 后端确保启用CORS(跨域资源共享),以避免浏览器限制。在 `server.js` 中添加: ```javascript const cors = require('cors'); app.use(cors()); // 允许所有跨域请求 ``` 安装CORS模块:`npm install cors`。 - 后端处理请求时,返回JSON格式响应,与前端拦截器匹配。 #### 4. **封装的优势注意事项** - **优势**:通过拦截器统一处理错误认证,减少重复代码[^1];API函数封装使组件更简洁。 - **注意事项**:确保后端地址正确;生产环境需替换为真实域名;处理跨域问题时,可使用代理(在Vue的 `vue.config.js` 中配置 `devServer.proxy`)。 这种封装方法已被广泛用于企业级Vue项目,能有效提升开发效率[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值