SPA單應用-請求介面URL結構設計

muniz發表於2019-04-07

需求

在開發一個SPA應用時,必然會遇到與後臺介面進行ajax的互動。為了專案結構的維護性、可讀性,我們總會去做一些相應的處理。如:

  • URL集中管理
  • 攔截請求
  • 攔截響應

在這裡,我們主要去實現URL的集中管理方案。

丟擲問題

v1: 需求問題

  • 如何集中管理URL
  • 如何提取出請求地址中相同的內容
  • 如何區分介面環境,如['開發環境','上線環境']

v2: 需求問題

  • 如何在定義URL時,只寫入不同的url即可。相同內容自動拼接,無需前置人為的拼接。
  • 如何根據不同的路由型別,去區分請求介面的型別。

技術可行性分析

v1: 需求解決思路

  • 可以使用ES6 import export 的方法實現 URl集中管理
  • 可以使用“變數拼接、字串模版解析”的方式,去提取地址中相同的內容
  • 可以使用 process.env.NODE_ENV 自定義環境變數,識別此時的執行環境

v2: 需求解決思路

  • 可以使用ES6 中的 proxy 實現

程式碼實現

v1: code

// 聯調環境介面判斷
const baseUrlEnv = {
  development: '/test',
  production: '/online'
};

// 請求介面地址
const baseUrl = 'http://www.xxx.com/' + baseUrlEnv[process.env.NODE_ENV];

// 定義URL
const URLSource = {
    // 這裡定義 account 主要是為了更加的細化請求地址
  account: { // 賬戶型別介面
    userInfo: baseUrl + '/v1/getUserInfo',
    userlist: `${baseUrl}/v1/getUserList`, 
  }
};

export default URLSource;


複製程式碼

v2: code

// 定義URL
const URLSource = {
    // 這裡定義 account 主要是為了更加的細化請求地址
  account: { // 賬戶型別介面
    userInfo: '/v1/{type}/getUserInfo',
    userlist: '/v1/{type}/getUserList', 
  }
};

// 聯調環境介面判斷
const baseUrl = {
  development: '/test',
  production: '/online'
};


// 代理監聽 URL配置
const handler = {
  get(target, key) { // get 的trap 攔截get方法
    let value = target[key];
    try {
      return new Proxy(value, handler); // 使用try catch 巧妙的實現了 深層 屬性代理
    } catch (err) {
      if (typeof value === 'string') {
        // 向請求地址動態繫結執行環境 如: test
        value = baseUrl[process.env.NODE_ENV] + value;

        // 替換當前瀏覽器的型別 通過獲取路由中的第一個路徑去區分
        if (value.includes('{type}')) {
          // 獲取 當前瀏覽器 pathName 路由中的第一個型別
          let currentType = window.location.pathname.split('/').filter((item) => {
            return item;
          });
          currentType = currentType.length > 0 ? currentType[0].toLocaleLowerCase() : '';
          if (['china', 'Korea'].includes(currentType)) {
            value = value.replace('{type}', currentType);
          }
        }
      }
      return value;
    }
  },
  set(target, key) { // 阻止外部誤操作,導致URL配置檔案被修改,設定屬性為只讀屬性
    try {
      return new Proxy(target[key], handler);
    } catch (err) {
      return true;
    }
  }
};

const URL = new Proxy(URLSource, handler);

export default URL;
複製程式碼

相關文章