知识点-fetch认识和使用
fetch认识和使用
1、认识Fetch
Fetch 主要被设计为替代 XMLHttpRequest(XHR)的 API
使用方法
// .then()使用
fetch(url)
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
// 使用 async/await
async function fetchData() {
try {
let response = await fetch(url);
let data = await response.json();
console.log(data);
} catch (error) {
console.error('Error:', error);
}
}
错误处理
fetch(url)
.then(response => {
if (!response.ok) {
throw new Error('Network response was not ok');
}
return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
设计原因
(1)解决的主要问题
XMLHttpRequest 使用回调函数(callbacks)来处理异步操作,导致代码容易陷入“回调地狱”(callback hell),而且不容易进行错误处理和链式操作。 Microsoft提出,2006年标准化。
Fetch 基于 JavaScript 的 Promise,能够使用 .then() 和 catch() 处理异步结果,或者使用 async/await,简洁、可读,易维护。Fetch由 WHATWG(Web Hypertext Application Technology Working Group)(Web 超文本应用技术工作组)正式提出的 API, 2015年正式成为标准。
(2)功能性设计
XMLHttpRequest的 API 复杂,开发者需要手动设置请求头、处理请求的各种状态(如onreadystatechange),并且需要多次调用方法来设置请求属性。Fetch提供了简洁统一接口
**(3)**跨域请求(CORS)
XMLHttpRequest 的跨域请求(CORS需要配置服务器支持 CORS
Fetch自动遵循浏览器的 CORS 策略,开发者只需要处理 CORS 请求的相关头部即可。
**(4)**灵活性
Fetch支持更丰富的 HTTP 方法和请求配置,例如支持GET、POST、PUT、DELETE等 HTTP 方法,并且能够更加灵活地配置请求头、请求体和其他选项。它还可以方便地处理 JSON、文本、Blob 和其他格式的数据。XMLHttpRequest的配置繁琐,需要手动管理每个步骤,尤其是一些复杂的请求(如带有复杂数据体的POST请求)处理起来较为繁琐
fetch 是浏览器原生支持的 API,用于发起 HTTP 请求。
axios 是一个基于 Promise 的库,提供了一些简化的功能和默认配置。底层是基于 XMLHttpRequest(用于浏览器环境)和 http/https 模块(用于 Node.js 环境)来进行实际的请求操作。
尽管 fetch 本身也可以完成所有 axios 的功能,但 axios 提供了更为便捷的功能,如自动转换 JSON 数据、请求/响应拦截器、取消请求等。
在项目中使用 fetch 代替 axios,可以通过封装 fetch 来实现类似 axios 的功能,并在项目中统一调用
2、使用Fetch
之前我们的请求方案都是使用axios进行请求的,接下来使用Fetch来代替
🍎封装src\utils\request.ts部分
使用fetch先来替代axios部分进行正常的一个请求的封装
// src/utils/request.js
import config from '@/utils/config'; //全局配置
interface RequestParams {
url: string;
method?: string;
data?: any;
headers?: Record<string, string>;
}
// const BASE_URL = `http:${import.meta.env.VITE_BASE_IP}:${import.meta.env.VITE_BASE_PORT}/${import.meta.env.VITE_PREFIX_API}/`;
// console.log(BASE_URL,'BASE_URL');
// baseURL: config.baseURL + config.prefixAPI,
const BASE_URL = `${config.baseURL}${config.prefixAPI}`;
// BASE_URL
export default async function request({ url, method = 'GET', data = null, headers = {} }: RequestParams) {
const defaultHeaders = {
'Content-Type': 'application/json',
...headers
};
try {
const response = await fetch(BASE_URL+url, {
method,
headers: defaultHeaders,
body: data ? JSON.stringify(data) : null
});
// 如果状态码不是 2xx,则抛出错误
if (!response.ok) {
throw new Error(`Request failed with status: ${response.status}`);
}
// 解析响应的 JSON 数据
const responseData = await response.json();
return responseData;
} catch (error) {
console.error('Request Error:', error);
throw error; // 抛出错误以供调用者处理
}
}
🍎完善头部信息
在axios的请求之中我们头部往往需要有token信息,这里我们配置一下
token我们先从本地开始进行取出
// 从localStorage或其他地方获取token
const token = localStorage.getItem('AdminToken');
const defaultHeaders = {
'Content-Type': 'application/json',
// 如果token存在,添加到Authorization头
...(token && { Authorization: `Bearer ${token}` })
};
3、参数详情
<template>
<div class="demo-container">
<h2>Fetch 配置示例</h2>
<button @click="fetchData">发起请求</button>
<div v-if="loading" class="loading">加载中...</div>
<div v-if="error" class="error">{{ error }}</div>
<pre v-if="data" class="result">{{ JSON.stringify(data, null, 2) }}</pre>
</div>
</template>
<script setup>
import { ref } from 'vue'
const data = ref(null)
const loading = ref(false)
const error = ref(null)
const fetchData = async () => {
try {
loading.value = true
error.value = null
// Fetch 配置示例
const response = await fetch('https://api.example.com/data', {
// 请求方法
method: 'GET', // 'GET', 'POST', 'PUT', 'DELETE', 'PATCH' 等
// 请求头
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-token',
'Accept': 'application/json',
'X-Custom-Header': 'value',
// 可以添加任意自定义头部
},
// 请求体
body: JSON.stringify({
key: 'value',
// 请求体数据
}),
// 模式
mode: 'cors', // 'cors', 'no-cors', 'same-origin'
// 凭证
credentials: 'include', // 'include', 'same-origin', 'omit'
// 缓存
cache: 'default', // 'default', 'no-store', 'reload', 'no-cache', 'force-cache', 'only-if-cached'
// 重定向
redirect: 'follow', // 'follow', 'error', 'manual'
// 引用策略
referrer: 'no-referrer', // 'no-referrer', 'client', 或 URL
// 引用策略
referrerPolicy: 'no-referrer-when-downgrade',
// 完整性
integrity: 'sha256-abcdef1234567890',
// 保持连接
keepalive: true,
// 信号
signal: new AbortController().signal,
// 优先级(实验性功能)
priority: 'high', // 'high', 'low', 'auto'
})
// 检查响应状态
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
}
// 解析响应
const result = await response.json() // 或 response.text(), response.blob(), response.arrayBuffer()
data.value = result
} catch (e) {
error.value = e.message
console.error('Fetch error:', e)
} finally {
loading.value = false
}
}
</script>
<style scoped>
.demo-container {
max-width: 800px;
margin: 20px auto;
padding: 20px;
}
button {
padding: 10px 20px;
margin-bottom: 20px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
}
button:hover {
background-color: #45a049;
}
.loading {
color: #666;
font-style: italic;
padding: 10px;
}
.error {
color: #ff4444;
padding: 10px;
background-color: #fff3f3;
border-radius: 4px;
margin: 10px 0;
}
.result {
background-color: #f5f5f5;
padding: 15px;
border-radius: 4px;
overflow-x: auto;
white-space: pre-wrap;
}
</style>
- 点赞
- 收藏
- 关注作者
评论(0)