SpringBoot + Vue + ElementUI 實現後臺管理系統模板 -- 前端篇(三):引入 js-cookie、axios、mock 封裝請求處理以及返回結果

来源:https://www.cnblogs.com/l-y-h/archive/2020/05/25/12955001.html
-Advertisement-
Play Games

前提: (1) 相關博文地址: SpringBoot + Vue + ElementUI 實現後臺管理系統模板 -- 前端篇(一):搭建基本環境:https://www.cnblogs.com/l-y-h/p/12930895.html SpringBoot + Vue + ElementUI 實現 ...


前提:

(1) 相關博文地址:

SpringBoot + Vue + ElementUI 實現後臺管理系統模板 -- 前端篇(一):搭建基本環境:https://www.cnblogs.com/l-y-h/p/12930895.html
SpringBoot + Vue + ElementUI 實現後臺管理系統模板 -- 前端篇(二):引入 element-ui 定義基本頁面顯示:https://www.cnblogs.com/l-y-h/p/12935300.html

 

(2)代碼地址:

https://github.com/lyh-man/admin-vue-template.git

 

一、引入 js-cookie

1、簡介

  為了保存 token 值,可以使用 cookie 或者 localStorage 或者 sessionStorage 保存。
  此處採用 cookie 進行保存,所以引入 js-cookie 插件,用於操作 cookie。

2、token

(1)簡單理解一下 token 是什麼?
  直譯為 “令牌”,是由服務端生成的一串字元串,作為客戶端進行請求的一個標識。

(2)token 一般用在什麼時候?
  一般用於用戶第一次登錄系統時,服務端生成一個 token,返回給客戶端,客戶端下次請求時帶上這個 token 發送請求,不用再帶上用戶名和密碼,簡化了驗證操作。

(3)為什麼使用 token?
  HTTP 協議是一種無狀態的協議,客戶端發送請求時,服務端並不知道是哪個客戶端在訪問。可以使用 用戶名以及密碼 唯一確定用戶身份,但是每次響應請求時都要驗證一下用戶,這就很煩。
  可以使用 session 以及 sessionId 的方式去解決,當客戶登錄系統時,服務端驗證並生成一個記錄保存在 session 中,並將這條記錄的 id(即 sessionID) 返回給 客戶端,客戶端使用 cookie 或者 localStorage 保存,再次發送請求時,帶上這個 sessionID,服務端響應並找到對應的記錄進行驗證。
  可以使用 token 的方式解決,當客戶登錄系統時,服務端驗證並返回一個 token 給客戶端,客戶端下次發送請求時,帶上這個 token,服務端驗證 token 即可。

(4)session 與 token 區別?
  session 存儲是需要空間的(存儲用戶信息),伺服器需要單獨保存一份,以空間換時間。
  token 可以不用存儲用戶信息,伺服器不用保存(解密 token 即可),以時間換空間。

3、安裝、引入 js-cookie

(1)npm 安裝 js-cookie

【使用 npm 安裝:】
    npm install js-cookie

 

 

 

(2)引入 js-cookie
  此處直接定義 一個 auth.js 並引入,使用時引入 該 js 文件即可。
  也可使用 main.js 全局引用。

【在項目中引入 js-cookie:】
// 引入 token,此處直接引入,也可以在 main.js 中全局引入
import Cookies from 'js-cookie'

// 設置 token 存儲的 key
const TokenKey = 'Admin-Token'

// 獲取 token
export function getToken() {
  return Cookies.get(TokenKey)
}

// 設置 token
export function setToken(token) {
  return Cookies.set(TokenKey, token)
}

// 移除 token
export function removeToken() {
  return Cookies.remove(TokenKey)
}

 

 

二、引入、封裝 axios

1、簡介

  想要發送 ajax 請求,vue 項目中一般使用 axios,使用起來雖然簡單,但如果不進行統一封裝,隨著項目越來越大,冗餘代碼會急劇增加,所有需要對 axios 進行二次封裝,使各個組件間能夠復用 axios,簡化代碼。

【vue 引入 axios 並簡單使用 參考地址:】
    https://www.cnblogs.com/l-y-h/p/11656129.html

 

2、封裝要求

  統一 url 配置(可以與代理結合起來使用解決跨域問題)。
  定義請求攔截器(request),比如:設置消息頭、設置 token 等。
  定義響應攔截器(response),比如:統一錯誤處理、頁面重定向 等。

3、引入 axios

(1)npm 安裝 axios

【npm 安裝】
    npm install axios

 

 

(2)引入 axios
  此處直接定義 一個 httpRequest.js 引入,使用時引入 該 js 文件即可。
  也可使用 main.js 全局引用。

import Vue from 'vue'
import {
    getToken,
    removeToken
} from '@/http/auth.js'
import router from '@/router'
import {
    Message
} from 'element-ui'
import axios from 'axios'

// 創建 axios 實例
const http = axios.create({
    // 統一 url 配置,定義訪問首碼 baseURL
    baseURL: '/api',
    // 定義請求超時時間
    timeout: 10000,
    // 請求帶上 cookie
    withCredentials: true,
    // 定義消息頭
    headers: {
        'Content-Type': 'application/json; charset=utf-8'
    }
})

// 定義請求攔截器
http.interceptors.request.use(
    config => {
        // 讓每個請求攜帶 token
        config.headers['Admin-Token'] = getToken()
        return config
    },
    error => {
        Promise.reject(error)
    }
)

// 定義響應攔截器
http.interceptors.response.use(
    response => {
        const res = response.data
        // 當 token 失效時,清除 cookie 保存的 token 值,並跳轉到登陸界面
        if (res && res.code === 401) {
            removeToken()
            Message({
                message: res.message,
                type: 'error',
                duration: 5000
            })
            router.push({
                name: 'Login'
            })
        }
        // 未找到頁面時,跳轉到 404 頁面
        if (res && res.code === 404) {
            router.push({
                name: '404'
            })
        }
        return response
    },
    error => {
        return Promise.reject(error)
    }
)

export default http

 

 

(3)全局掛載 axios
  在 main.js 中引入 httpRequest.js 文件,並全局掛載。

import http from '@/http/httpRequest.js'

// 全局掛載 http(axios),使用的時候直接使用 this.$http 即可。
Vue.prototype.$http=http

 

 

(4)簡單寫個案例測試一下:(僅供參考)
後端:
  定義一個 AuthController,用於返回 token。
其中:
  @CrossOrigin 用來解決跨域(一般加上這個即可跨域)。如果此註解不生效,可以在前端配置代理來實現跨域。

package com.lyh.template.back.controller;

import com.lyh.template.back.util.Result;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/auth")
@CrossOrigin
public class AuthController {
    @RequestMapping("/token")
    public Result getToken() {
        return Result.ok().data("token", "admin");
    }
}

 

 

如下,介面訪問正常(當然,使用 swagger 測試也一樣)。

 

 

前端:
  修改代理,用於跨域。
  在 vue.config.js 文件中進行配置,當路徑中出現 /api 時,會將其替換成 target 中的路徑。
  而 target 路徑是從 配置文件中讀取的,生產環境與開發環境的 VUE_APP_URL 不同。
註:
  開發環境時:
    VUE_APP_URL=http://localhost:8000
  生產環境時:
    VUE_APP_URL=http://localhost:9000

module.exports = {
    lintOnSave: false,
    devServer: {
        port: process.env.NODE_ENV == "production" ? 8000 : 9000,
        proxy: {
            '/api': {
                target: process.env.VUE_APP_URL,
                // 允許跨域
                changeOrigin: true,
                ws: true,
                pathRewrite: {
                    '^/api': ''
                }
            }
        }
    }
}

 

 

修改一下 Login 組件中的登陸方法,測試一下。
  發送 /auth/token 請求時,會代理到 http://localhost:8000/auth/token。
  登錄成功後,會列印返回數據,並跳轉到主界面。

methods: {
    // 提交表單
    dataFormSubmit() {
    // TODO:登錄代碼邏輯待完善
    // alert("登錄代碼邏輯未完善")
    this.$http({
        url: '/auth/token',
        method: 'get'
    }).then(response => {
        console.log(response)
        this.$router.replace({name: 'Home'})
    })
    }
}

 

 

三、引入、封裝 mock

1、簡介

  項目開發的時候,有時候後端介面不給力,要是必須從後端獲取數據,沒有其他方式獲取數據,那就很蛋疼了(只能等後端介面正常,才可以繼續開發前端)。
  mock 是一個數據模擬生成器,用於幫助前端獨立於後端進行開發,其模擬 ajax 並返回相應的數據,從而使前端不必依賴於後端介面,方便開發。

【vue關於mock的簡單使用 參考地址:】
    https://www.cnblogs.com/l-y-h/p/11691110.html

 

2、封裝要求

  定義不同的模塊,用於響應不同組件的請求。
  可以方便、快捷的關閉某個模塊、或者某個請求的處理(關閉請求處理後,可以直接訪問後端介面)。

3、引入 mock

(1)npm 安裝 mock

【npm 安裝 mock:】
    npm install mockjs

 

 

(2)引入 mock
  定義一個 mock 文件夾以及統一處理入口 mock.js。
  定義一個 fnCreate 方法 用來處理 mock。
其中:
  第一個參數為 模塊名,需要通過 import 引入。
  第二個參數為 是否開啟 mock ,true 為開啟,false 為關閉。

import Mock from 'mockjs'
import * as login from './modules/login.js'

// 可以通過 isOpen 參數設置是否攔截整個模塊的 mock 功能
fnCreate(login, true)

/**
 * 創建mock模擬數據
 * @param {*} mod 模塊
 * @param {*} isOpen 是否開啟?
 */
function fnCreate(mod, isOpen = true) {
    if (isOpen) {
        for (var key in mod) {
            ((res) => {
                if (res.isOpen !== false) {
                    Mock.mock(new RegExp(res.url), res.type, (opts) => {
                        opts['data'] = opts.body ? JSON.parse(opts.body) : null
                        delete opts.body
                        console.log('\n')
                        console.log('%cmock攔截, 請求: ', 'color:blue', opts)
                        console.log('%cmock攔截, 響應: ', 'color:blue', res.data)
                        return res.data
                    })
                }
            })(mod[key]() || {})
        }
    }
}

 

 

(3)定義功能子模塊
  給不同的組件定義不同的模塊,用於區分不同的操作。
比如創建一個 login.js 用來處理 登錄、登出操作。

import Mock from 'mockjs'

// 登錄
export function getToken() {
    return {
        // isOpen: false,
        url: 'api/auth/token',
        type: 'get',
        data: {
            'msg': 'success',
            'code': 0,
            'expire': Mock.Random.natural(60 * 60 * 1, 60 * 60 * 12),
            'token': Mock.Random.string('abcdefghijklmnopqrstuvwxyz0123456789', 32)
        }
    }
}

 

 

(4)全局引入 mock 文件
  在 main.js 中引入,可以控制引入時機,比如只在開發環境下生效。

// 非生產環境, 適配mockjs模擬數據
if (process.env.NODE_ENV !== 'production') {
    require('@/mock')
}

 

 

(5)簡單測試一下。
  開發環境運行時,登錄會觸發 mock ,在控制台列印數據。

 

 

 

 

(6)與後臺介面的區別。
  使用 mock 返回數據 與 訪問後臺介面還是有區別的。
開發環境下,若想訪問後臺,
  方式一:可以在 main.js 中將 引入 mock 文件的代碼註釋掉,就可以訪問了。

 

 

  方式二:在 mock 的 fnCreate 方法中,將 isOpen 參數置為 false 即可(關閉 mock 功能)。

 

 

  生產環境下,執行 dist 項目,可以通過 nginx 反向代理到後臺伺服器,進行訪問(後續項目部署時再補充)。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • vue3.0 beta已出,來快速實踐一下吧 "本文視屏" "我的個人博客" vue3向下相容vue2,vue2目前也是必學的 本節源碼 "立即前往" 前段時間尤大在嗶哩嗶哩直播了vue3的預覽,來簡單實踐一下吧 api文檔 Composition API RFC "立即前往" vue3地址 "立即 ...
  • 在我們開發Vue應用的時候,很多時候需要記錄一些變數的內容,這些可以用來做界面狀態的承載,也可以作為頁面間交換數據的處理,處理這些內容可以歸為Vuex的狀態控制。例如我們往往前端需要訪問後端數據,一般是通過封裝的Web API調用獲取數據,而使用Store模式來處理相關的數據或者狀態的變化,而視圖V... ...
  • # 概述 - 1.新增的屬性 placeholder Calendar, date, time, email, url, search ContentEditable Draggable Hidden Context-menu Data-Val(自定義屬性) - 2.新增的標簽 語義化標簽(一群類似 ...
  • 因人而異 自學肯定也是可以的,最主要還是要看個人的學習能力,意志力,和自己的決心, 下麵我就說一下,在自學時需要註意的一些誤區和需要掌握哪些技術知識,才能去找工作。 前端自學者存在的學習誤區: 1、所學東西可能已過時 奉為經典的東西可能已經過時,或者已經有了更好的替代者,而你獲取信息的渠道有限,消息 ...
  • 隨著技術以如此快的速度發展,現在我們有必要選擇合適的工具來使用。每個軟體項目都有它需要滿足的多個需求和規範,因此為了滿足這些需求,選擇一種編程語言以允許您以有效的方式開發和管理項目非常重要。 由於有許多種編程語言和框架可供選擇,它們之間的比較已成為必然,因為你需要知道哪一個提供了最好的服務。當涉及到 ...
  • 什麼是NodeJS JS是腳本語言,腳本語言都需要一個解析器才能運行。對於寫在HTML頁面里的JS,瀏覽器充當瞭解析器的角色。而對於需要獨立運行的JS,NodeJS就是一個解析器。 每一種解析器都是一個運行環境,不但允許JS定義各種數據結構,進行各種計算,還允許JS使用運行環境提供的內置對象和方法做 ...
  • 之前一直採用VS進行各種前端後端的開發,隨著項目的需要,正逐步融合純前端的開發模式,開始主要選型為Vue + Element 進行BS前端的開發,後續會進一步整合Vue + AntDesign的界面套件,作為兩種不同界面框架的展現方式。採用Vue + Element 的前端開發和之前的開發模式需要有... ...
  • 從事web前端6年的工作,曾經是信息管理的一名應屆生,由於專業難找工作,掙錢少,當時選擇了轉行學前端開發技術,今天師兄就給大家講一下,作為應屆生,想學前端快點找工作應該如何去學。 對於畢業生來說,最要緊的事情就是快點找到工作。所以你學前端的時候就抓重點來學,因為很多東西,工作上用不到,所以學了也沒必 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...