面试题答案
一键面试利用 fetch
与 axios
的特性
fetch
特性:- 现代浏览器原生支持,轻量级,基于Promise。
- 可以灵活控制请求和响应,例如设置请求头、处理不同类型的响应(JSON、文本等)。
- 对于简单请求(符合CORS简单请求条件),不需要额外处理跨域问题,浏览器会自动处理。
axios
特性:- 支持浏览器和Node.js环境,功能丰富。
- 自动转换请求和响应数据,如将JSON数据自动解析为JavaScript对象。
- 具有良好的拦截器机制,可以在请求发送前和响应接收后进行统一处理,如添加认证头、处理错误等。
- 对跨域请求有较好的支持,可以通过配置
baseURL
等方式简化请求。
结合Qwik的生命周期和状态管理机制
- Qwik生命周期:
use$
钩子函数可以用于在组件初始化、更新和销毁时执行副作用操作。例如,在组件初始化时发起API请求。onMount
生命周期钩子可以确保在组件挂载到DOM后执行特定代码,适合发起需要DOM存在的API请求。
- Qwik状态管理:
- 使用
useStore
创建可响应式的状态存储。可以将API请求的结果存储在状态中,以便组件根据状态变化进行重新渲染。 - 利用状态管理机制来跟踪请求的加载状态(如
loading
状态),从而在界面上显示加载指示器。
- 使用
关键代码实现
- 使用
fetch
:import { use$, onMount } from '@builder.io/qwik'; const MyComponent = () => { const [data, setData] = use$(null); const [loading, setLoading] = use$(false); onMount(async () => { setLoading(true); try { const response = await fetch('https://api.example.com/data'); if (!response.ok) { throw new Error('Network response was not ok'); } const result = await response.json(); setData(result); } catch (error) { console.error('Error fetching data:', error); } finally { setLoading(false); } }); return ( <div> {loading && <p>Loading...</p>} {data && <pre>{JSON.stringify(data, null, 2)}</pre>} </div> ); }; export default MyComponent;
- 使用
axios
:import { use$, onMount } from '@builder.io/qwik'; import axios from 'axios'; const MyComponent = () => { const [data, setData] = use$(null); const [loading, setLoading] = use$(false); onMount(async () => { setLoading(true); try { const response = await axios.get('https://api.example.com/data'); setData(response.data); } catch (error) { console.error('Error fetching data:', error); } finally { setLoading(false); } }); return ( <div> {loading && <p>Loading...</p>} {data && <pre>{JSON.stringify(data, null, 2)}</pre>} </div> ); }; export default MyComponent;
- 处理不同认证机制:
fetch
:onMount(async () => { setLoading(true); const headers = new Headers(); headers.append('Authorization', 'Bearer your_token'); try { const response = await fetch('https://api.example.com/data', { headers }); if (!response.ok) { throw new Error('Network response was not ok'); } const result = await response.json(); setData(result); } catch (error) { console.error('Error fetching data:', error); } finally { setLoading(false); } });
axios
:import axios from 'axios'; const instance = axios.create({ baseURL: 'https://api.example.com', headers: { Authorization: 'Bearer your_token' } }); onMount(async () => { setLoading(true); try { const response = await instance.get('/data'); setData(response.data); } catch (error) { console.error('Error fetching data:', error); } finally { setLoading(false); } });
- 处理跨域:
fetch
:如果是简单请求,浏览器自动处理跨域。对于复杂请求(如PUT、DELETE请求,或包含自定义头部的请求),需要服务器端设置正确的CORS头(Access - Control - Allow - Origin
等)。axios
:可以通过配置代理(在开发环境)来解决跨域问题,例如在webpack.config.js
中配置:
然后在代码中使用相对路径请求,如devServer: { proxy: { '/api': { target: 'https://api.example.com', changeOrigin: true } } }
axios.get('/api/data')
。
注意事项
- 错误处理:
- 无论是
fetch
还是axios
,都要妥善处理请求过程中的错误。fetch
需要检查response.ok
来判断请求是否成功,axios
可以通过catch
块捕获错误。
- 无论是
- 性能优化:
- 在高并发请求场景下,要避免不必要的重复请求。可以利用缓存机制,如在状态管理中存储已请求的数据,再次请求相同数据时先检查缓存。
- 对于频繁触发的请求,可以使用防抖(debounce)或节流(throttle)技术来限制请求频率。
- 认证管理:
- 妥善管理认证信息,如将认证令牌存储在安全的地方(如HTTP-only Cookie或本地存储,但本地存储有安全风险)。
- 当认证令牌过期时,要及时处理,如自动刷新令牌并重试请求。
- 网络不稳定处理:
- 可以实现重试机制,当请求失败时,根据一定的策略(如指数退避算法)进行重试。
- 提供用户友好的提示,告知用户网络不稳定或请求失败的情况。