vue接口请求库axios,fetch的使用

2024年05月22日 编程 暂无评论 阅读74 次

介绍

本文介绍一下axios的安装,配置,get,post和stream用法(封装方式),拦截器用法

安装

npm install axios

"axios": "^1.6.8",

request封装

request.js主要是对axios进行基本配置

import axios from 'axios'
export const API_BASE_URL = "http://192.168.68.92:16603";
const service = axios.create({  
    //url = base url + reqeust url  
    baseURL : API_BASE_URL,  
    //配置请求超时时间  
    timeout: 5000  
})

get请求

import axios from './request'

//get请求
export const getTest = (token)=>axios.get("/api/test",{  
    params:{  
        "token":token  
    }  
})

//get请求带header
export const getCaptch = ()=>axios.get("/captcha/refresh/",{  
    headers: {  
        'X-Requested-With': 'XMLHttpRequest'  
    },  
    params:{  
  
    }  
})

//get请求调用方式1
const fetchUserInfo = async () => {  
  try {  
    const response = await getUserInfo();  
    userInfo.value = response.data;  
    userInfo.value.image = `${API_BASE_URL}${result.image_url}`;  
  } catch (error) {  
    ElMessage.error('Failed to fetch user info.');  
    console.error('Error fetching user info:', error);  
  }  
};


//get请求调用方式2
refreshCaptcha() {  
  console.log("刷新验证码");  
  getCaptch()  
      .then(response => {  
        const result = response.data;  
        this.captchaSrc = `http://127.0.0.1:7080${result.image_url}`;  
        this.captchaKey = result.key;        // 更新验证码的键  
      })  
      .catch(error => {  
        console.error('Error refreshing the captcha:', error);  
      });  
}


import {getCaptch} from "@/api/getData.js";
const refreshCaptcha = () => {  
  console.log("刷新验证码");  
  getCaptch()  
      .then(response => {  
        const result = response.data;  
        captchaSrc.value = `${API_BASE_URL}${result.image_url}`;  
        captchaKey.value = result.key; // 更新验证码的键  
      })  
      .catch(error => {  
        console.error('Error refreshing the captcha:', error);  
      });  
};

post请求

export const potsendEmailCode= (email,captchaKey,captchaValue)=>axios.post("/register/verifyEmailcaptcha/",{  
    'email': email,  
    'captcha_key': captchaKey,  
    'captcha_value': captchaValue,  
})

export const registerUser = (email, emailCode, nickName, pw, pw2) => {  
    return axios.post("/register/createUser/", {  
        'email': email,  
        'email_code': emailCode,  
        'nick_name': nickName,  
        'pw': pw,  
        'pw2': pw2,  
    });  
}


//调用
registerUser(  
    form.value.email,  
    form.value.emailCode,  
    form.value.nickname,  
    form.value.password,  
    form.value.confirmPassword  
)  
    .then(response => {  
      ElMessage.success('注册成功');  
      // 在这里处理注册成功后的逻辑,例如跳转到登录页面  
      router.push('/login');  
    })  
    .catch(error => {  
      console.error('Error registering user:', error);  
      if (error.response && error.response.data) {  
        const errors = error.response.data;  
        for (const key in errors) {  
          if (errors.hasOwnProperty(key)) {  
            ElMessage.error(errors[key].join(', '));  
          }  
        }  
      } else {  
        ElMessage.error('注册失败,请检查输入项');  
      }  
    });

拦截器用法

request.js加下面代码

//所有接口请求的时候给头部添加JWT用户身份信息
service.interceptors.request.use(  
    config => {  
        const userStore = useUserStore();  
        if (userStore.token) {  // 判断是否存在token,如果存在的话,则每个http header都加上token  
            config.headers.Authorization = `JWT ${userStore.token}`;  
        }  
        return config;  
    },  
    err => {  
        return Promise.reject(err);  
    }  
);

 

fetch与stream用法

stream是流式接口,接口数据不是一次性返回的。流行的比如chatgpt就使用这种接口
流式请求要使用fetch的封装,不使用axios

//先进行一个请求封装
export const fetchStreamData = async (url, params, onData, onComplete) => {  
    const targetUrl = new URL(API_BASE_URL + url);  
  
    // 添加查询参数  
    if (params) { // 此处判断会排除null和undefined的情况  
        Object.keys(params).forEach(key => {  
            targetUrl.searchParams.append(key, params[key]);  
        });  
    }  
  
    const response = await fetch(targetUrl);  
    const reader = response.body.getReader();  
  
    const processText = async ({ done, value }) => {  
        if (done) {  
            onComplete(); // 调用流完成的回调  
            return;  
        }  
        onData(decoder.decode(value, { stream: true })); // 处理接收到的数据块  
        reader.read().then(processText); // 递归读取下一个数据块  
    };  
  
    reader.read().then(processText);  
};



//接口定义
import { fetchStreamData } from "./request";  
  
//测试接口  
export const getTest = (token, onData, onComplete) => {  
    // 使用token构建params对象  
    const params = { token: token };  
  
    // 调用fetchStreamData,并传入构建好的params  
    fetchStreamData("/stream", params, onData, onComplete);  
}  
  
//同步feed列表  
export const syncFeed = (onData, onComplete) => {  
    // 调用fetchStreamData,并传入构建好的params  
    fetchStreamData("/start_syncfeed", null, onData, onComplete);  
}

//接口使用
import {ref} from "vue";  
import {getTest} from "../api/getStreamData";
const dataBlocks = ref([]);  
const inputdata = ref("");

function fetchStreamData() {  
  getTest(inputdata.value,  
      (data)=>{  
        dataBlocks.value.push(data);  
      },  
      ()=>{  
        // 处理流结束  
        console.log('Stream finished.');  
      }  
  )  
}

<div>  
  <span v-for="(block, index) in dataBlocks" :key="index">  
    {{ block }}<br/>  
  </span></div>
# django的流式接口例子
@csrf_exempt  
def testStream(request):  
    if request.method == 'POST':  
        print("testStream")  
        data = json.loads(request.body.decode('utf-8'))  
        token = data.get('token')  # 从POST数据中获取feed_id  
  
        if not token:  
            return HttpResponse("articleid参数不能为空", status=400)  
  
        response = StreamingHttpResponse(TestService.testStream(token),  
                                         content_type="text/event-stream; charset=utf-8")  
        response['Cache-Control'] = 'no-cache'  
        return response  
    else:  
        # 如果不是POST请求,返回错误或其他处理  
        return JsonResponse({'error': 'Invalid request'}, status=400)

def testStream(token):  
    yield LogUtil.send_log(f"token:{token}")  
    for i in range(10):  
        yield LogUtil.send_log(f"轮次:{i}")  
    # yield LogUtil.send_log(f"{answer}")  
    print("调用结束")

def send_log(message):  
    """  
    封装发送日志信息的方法。  
    :param message: 要发送的消息文本  
    """    #print(message)  
    print(message.encode('GBK','ignore').decode('GBK','ignore'))  
    sys.stdout.flush()  
    return f"{message}\n"  
  
def send_long_log(message):  
    print(message)  
    sys.stdout.flush()  
    # 使用split('\n')方法按照回车分割字符串  
    # 统一行终止符:将\r\n替换为\n  
    message = message.replace('\\n', '\n')  
    lines_list = message.split('\n')  
    print(f"lines_list长度: {len(lines_list)}")  
    # 遍历得到的列表并打印每一项  
    for line in lines_list:  
        if line.strip():  
            yield send_log(line)
标签:

给我留言

登录

忘记密码 ?

切换登录

注册