您现在的位置是:首页 >学无止境 >微前端nuxt3.0方便请求api可封装一个使用哈希算法出key值的http,http封装网站首页学无止境

微前端nuxt3.0方便请求api可封装一个使用哈希算法出key值的http,http封装

zhongli_ 2024-06-17 10:48:26
简介微前端nuxt3.0方便请求api可封装一个使用哈希算法出key值的http,http封装

http.ts

import { hash } from 'ohash'

import type { FetchOptions } from 'ohmyfetch'

interface httpOptions {

  source?: string

}

/**** 获取接口前缀 */

我这里为不同站点的接口做了区分,主站点为api,demo站点为demoapi

function GetPrefixUrl(source?: string) {

const {public : config} = useRuntimeConfig();

  // 默认正式接口

  let API_BASE = {

    api: config.VITE_API,

    demoapi: config.VITE_DEMO_API,

  };

  let prefixUrl = '';

  switch (source) {

    case 'demo':

      prefixUrl = API_BASE.demoapi;

      break;

    default:

      prefixUrl = API_BASE.api;

      break;

  }

//不是微前端的可以忽略这个例子

  if (source === 'demoapi') {

    const prefixcode = process.client ? 'demoapi' : 'api'; //判断接口是服务端还是客户端请求

    return prefixUrl + prefixcode;

  } else {

    const prefixcode = process.client ? 'asyncapi' : 'api'; //判断接口是服务端还是客户端请求

    return prefixUrl + prefixcode;

  }

不是微前端的直接写:

const prefixcode = process.client ? 'asyncapi' : 'api'; 

return prefixUrl + prefixcode;

}

/** http 请求封装 */

export async function httpHandler<T, U extends httpOptions>(url: string, method: string, params: T | null, options: Partial<U> = {}) {

  const config: FetchOptions = {};

  const httpOptions = options;

  let prefixUrl = GetPrefixUrl(httpOptions.source);

  config.method = method;

  config.headers = useRequestHeaders(['user-agent','x-forwarded-for','x-real-ip','accept-encoding','accept-language']);// 加了x-real-ip的作用是获取用户真实ip,根据自己需求是否要获取用户真实ip来保留日志记录

  config.baseURL = prefixUrl;

  const token = useCookie('token').value

  if(token) {

    config.headers.Authorization = `${token}`

  }

  if(config.headers['x-forwarded-for'] == undefined && config.headers['x-real-ip'] != undefined){config.headers['x-forwarded-for'] = config.headers['x-real-ip']};

  if (params != null) {

    if (method === 'get') {

      config.params = params;

    } else {

      config.body = params;

    }

  }

  let rst: any = {};

  const key = hash(JSON.stringify(options) + url) // 使用hash算法获取不同的key值;当客户端传的参数不同时key值才会改变

  const response = await useAsyncData(key, () =>

    $fetch(url, config).catch((error) => {     

// 当token失效跳转登录页登录

      if(error.data.Code === 401) {        

        const redirect = route.path;

        window.location.href = `/login?redirect=${redirect}`;

      }

    })

  );

  rst = <any>response.data.value;

  switch (rst.Code) {

    case 0:  

      if(rst.Data)

      return rst.Data;

      break;

    case 401:

    case 403:

      // token 失效

      console.error(rst.Message);

      throw(rst.Message);

    default:

      console.error(rst.Message);

      throw(rst.Message);

  }

}

// type Partial<U> = {}

export async function httpGet<T, U>(url: string, options: Partial<U> = {}) {

  const rst = await httpHandler<T, U>(url, 'get', null, options);

  return rst;

}

export async function httpPost<T, U>(url: string, params?: T, options?: U) {  

  const rst = await httpHandler<T, U>(url, 'post', params, options);

  return rst;

}

api/api.ts api文件夹下的api.ts

import { httpPost, httpGet } from '~/utils/http';

// p是参数

export const 组件使用名= (p: any) => httpPost('接口名', p);

// demo是不同站点的来源;不是微前端的可以忽略这个例子

export const 组件使用名= (p: any) => httpPost('接口名', p, demo);

demo.vue

import { 组件使用名,组件使用名1,组件使用名2 } from '~/api/api;

const data = await 组件使用名(); // 服务端请求

const [data1, data2] = await Promise.all([组件使用名1(),组件使用名2()]) // 多个接口请求

//客户端请求

const data  = ()=> {

组件使用名().then(()=>{})

}

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。