vue接口请求库axios,fetch的使用
介绍
本文介绍一下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)