axios请求
Axios 是前端最流行的 ajax 请求库
shell
基于 XMLHttpRequest(JS原生) + Promise(JS原生) 的异步的 Ajax 请求库
react项目中使用axios发送ajax请求
shell
# 如果是首屏数据渲染
发送请求的位置 ==> componentDidMount
# 如果是用户交互
用户点击了一个按钮、用户做了xxx操作
创建axios实例
创建axios实例(request对象),设置axios请求的请求配置项
shell
# request 是一个简化版的 axios对象,没有cancelToken、all方法
const request = axios.create({
baseURL:'xxxx.com:8080',
timeout:20000
})
请求默认全局配置
shell
每次发送请求设置的配置项
# 设置默认路径 baseURL 属性
axios.defaults.baseURL = 'xxx.com:8080'
# 设置超时时间 baseURL 属性
axios.defaults.timeout = 5000
defaults属性是基础路径配置,只能配置一个基础路径
create() 方法可以创建多个request对象,配置多个基础路径
发送请求Api
使用axios(或axios的实例:request)发送请求有两种写法
request 是一个简化版的 axios对象,没有cancelToken、all方法
axios(request)函数式用法
axios(request)对象式用法
axios(或axios的实例:request)函数式用法
shell
# axios函数式用法:
语法:
axios(config)
config:{
method 请求方式: get 、post、patch、put、delete
url 请求地址
headers 请求头
params query参数
data 请求体
cancelToken 取消请求
timeout 请求超时
}
axios(或axios的实例:request)对象式用法
shell
# axios对象式用法:按照请求方式分成两类 [,config] 代表可选参数 空或者一个config对象
get、delete
axios.get(url,[,config])
axios.delete(url,[,config])
post、put、patch
axios.post(url,data,[,config])
axios.put(url,data,[,config])
axios.patch(url,data,[,config])
axios(或axios的实例:request)使用案例:两种写法
shell
# axios函数式用法
axios({
method:'get',
url:'zyx.com',
params:{
a:1,
b:2
}
})
axios({
method:'post',
url:'zyx.com',
data:{
username:'zyx',
age:20
}
})
# axios对象式用法
axios.get('/api/getDate',config)
设置拦截器
请求拦截器
shell
在请求头里可以携带公共的参数 token
开启loading效果 NProgress
安装
npm i nprogress
导入nprogress
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
js
const request = axios.create({
baseURL:'http://localhost:8080',
timeout:2000
})
request.interceptors.request.use(config=>{
// 1. 公共请求参数在请求头的携带,此处以token举例
let token = localStorage.getItem('token');
if(token){
config.headers.token = token;
}
// 2. 开启loading效果
NProgress.start();
return config;
})
响应拦截器
shell
关闭loading
简化响应数据
进行token鉴权,重定向到 登录页面
进行统一错误处理
js
const request = axios.create({
baseURL:'http://localhost:8080',
timeout:2000
})
request.interceptors.response.use(response=>{
// token鉴权,重定向处理
if(response.statusCode === 401){ // 说明token过期或token异常
// 重定向到login页面重新登录重新生成token
// 清除掉本地存储的token
localStorage.removeItem('token');
//
location.href = '/login.html'// 重定向到登录页
}
NProgress.done();// 关闭loading
return response.data;// 简化响应数据
},error=>{
// 进行统一错误处理
console.log("error:",error);
// 阻止promise链条向下传递
return new Promise(()=>{})
})
axios使用案例:项目中使用
js
1. 在src/request目录中对 axios对象设置请求配置项
2. 使用配置后的request对象发送ajax请求
- 封装request请求对象:src/request/index.js
js
// 做axios的基本配置:baseURL timeout 请求和响应拦截器
import axios from 'axios'
// 1. 安装nprogress npm i nprogress
// 2. 导入nprogress
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
const request = axios.create({
baseURL:'https://api.github.com',
timeout:2000
})
// 配置请求拦截器
request.interceptors.request.use(config=>{
// 1. 请求头中携带公共参数 token
// 2. 开启loading效果
NProgress.start()
return config;
})
// 配置响应拦截器
request.interceptors.response.use(response=>{
// 1. 关闭loading
NProgress.done()
// 2. 简化服务器数据
return response.data;
})
export default request; // 将配置好的axios暴露
- 在组件中使用请求配置对象发送请求:src->App.jsx
jsx
import React, { useState } from 'react'
// 导入配置号的request
import request from './request'
export default function App() {
let [count, setCount] = useState(100);
return (
<div>
<p>count: {count}</p>
<p><button onClick={async () => {
let res = await request.get('/search/users', {
params: {
q: 'aa'
}
})
let totalCount = res.total_count
console.log(totalCount);
setCount(count + totalCount);
}}>count+</button></p>
</div>
)
}
axios使用案例:axios-repo案例
shell
学习目标及知识点:
1. request.js, 封装axios基础配置
2. useEffect的回调函数不能使用async直接修饰,需要单独定义async函数,手动调用
3. loading 条件渲染
- 封装request请求对象:src/request/index.js
js
// 做axios的基本配置:baseURL timeout 请求和响应拦截器
import axios from 'axios'
// 1. 安装nprogress npm i nprogress
// 2. 导入nprogress
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
const request = axios.create({
baseURL:'https://api.github.com',
timeout:2000
})
// 配置请求拦截器
request.interceptors.request.use(config=>{
// 1. 请求头中携带公共参数 token
// 2. 开启loading效果
NProgress.start()
return config;
})
// 配置响应拦截器
request.interceptors.response.use(response=>{
// 1. 关闭loading
NProgress.done()
// 2. 简化服务器数据
return response.data;
})
export default request; // 将配置好的axios暴露
- 在组件中使用请求配置对象发送请求:src->App.jsx
jsx
import React, { useEffect, useState } from 'react'
import request from './request';
export default function App() {
let [loading, setLoading] = useState(false);// 请求加载中的标识符
let [repo, setRepo] = useState({}); // undefined.html_url
// componentDidMount
useEffect( () => { // useEffect中 的回调不能直接写 async, 需要单独定义async函数,在手动调用
// 定义函数
async function main(){
// 开启loading
setLoading(true);
let {items} = await request.get('/search/repositories', {
params: {
q: 'vue',
sort: 'stars'
}
})
// 设置仓库状态
setRepo(items[0])
setLoading(false);
}
// 调用函数
main()
}, [])
return (
<div>
{loading ? <h1>loading.....</h1> : <div>most star repo is <a href={repo.html_url}>{repo.name}</a></div>}
</div>
)
}
发送请求思路
js
1. 查看api接口地址:【请求方式、url、请求的参数、响应内容】
请求参数:
1-1. query参数: axios.get(url, {params:{query参数}})
1-2. path[params]参数: axios.get('url/1/3')后端是有占位符的
1-3. 请求体参数body
- get/delete: axios.get(url,{data:请求体参数})
- post、put、patch: axios.post(url, 请求体参数对象)
2. 封装api 请求的函数【使用该函数向api接口地址发送请求或取数据】
请求函数返回的都是Promise对象
3. 调用api函数获取数据
3-1. 在生命周期钩子中调用【首屏数据渲染】,一般是componentDidMount
3-2. 用户交互调用:用户点击了一个按钮、用户做了xxx操作
4. 用请求回来的数据渲染页面:
4-1. 定义响应状态,使用插值语法渲染
使用案例
github获取用户数据案例
封装request请求对象:src/request/index.js
js
// 做axios的基本配置:baseURL timeout 请求和响应拦截器
import axios from 'axios'
// 1. 安装nprogress npm i nprogress
// 2. 导入nprogress
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
const request = axios.create({
baseURL:'https://api.github.com',
timeout:2000
})
// 配置请求拦截器
request.interceptors.request.use(config=>{
// 1. 请求头中携带公共参数 token
// 2. 开启loading效果
NProgress.start()
return config;
})
// 配置响应拦截器
request.interceptors.response.use(response=>{
// 1. 关闭loading
NProgress.done()
// 2. 简化服务器数据
return response.data;
})
export default request; // 将配置好的axios暴露
封装api接口请求对象:src/api/github.js
js
/**
* 封装所有的github相关的请求函数
*
*/
import request from '../request'
/**
*
* @param {*} keyword 关键字
* @param {*} sortType 排序方式
* @returns Promise对象
*
*/
export function getRepo(keyword, sortType='stars'){
return request.get('/search/repositories',{
params:{
q:keyword,
sort:sortType
}
})
}
在组件中调用api请求发送请求:src->App.jsx
jsx
import React, { useEffect, useState } from 'react'
import { getRepo } from './api/github';
export default function App() {
useEffect(()=>{// componentDidMount
async function main(){
// 发送请求之前开启 loading
setLoading(true);
let res = await getRepo('vue')
console.log('res: ', res);
// 设置状态
setRepo(res.items[0])
// 请求结果回来之后,关闭loading
setLoading(false);
}
main();
},[])
// 定义状态
let [repo, setRepo] = useState({});
// 定义一个条件渲染的状态
let [loading, setLoading] = useState(false);
// 也可以在这里拦截,实现条件渲染
// if (loading) {
// return <h1>Loadding...</h1>
// }
return (
<div>
{loading ? <h1>loading....</h1> : <div>most stars repo is <a href={repo.html_url}>{repo.name}</a></div>}
</div>
)
}
github获取用户案例
引入Bootstrap:public->index.html
html
<title>React App</title>
<link rel="stylesheet" href="/css/bootstrap.css">
主组件:src->App.jsx
jsx
import React from 'react'
import './App.css'
import Header from './components/Header'
import Main from './components/Main'
export default function App() {
return (
<div className="container">
<Header />
<Main />
</div>
)
}
样式文件:src->App.css
css
.card {
float: left;
width: 33.333%;
padding: .75rem;
margin-bottom: 2rem;
border: 1px solid #efefef;
text-align: center;
}
.card>img {
margin-bottom: .75rem;
border-radius: 100px;
}
.card-text {
font-size: 85%;
}
子组件:src->components->Header.jsx
jsx
import React from 'react'
import PubSub from 'pubsub-js'
import { useRef } from 'react'
export default function Header() {
const inputRef = useRef();
return (
<section className="jumbotron">
<h3 className="jumbotron-heading">Search Github Users</h3>
<div>
<input ref={inputRef} type="text" placeholder="请输入用户名" />
<button onClick={() => {
// 1. 获取input文本框的输入
// 2. 将username数据 传递给兄弟组件 Main
let username = inputRef.current.value.trim()
// 发布消息
PubSub.publish('search', username);
}}>Search</button>
</div>
</section>
)
}
子组件:src->components->Item.jsx
jsx
import React from 'react'
export default function Item({user}) {
return (
<div className="card" key={user.id}>
<a href={user.html_url} target="_blank" rel="noreferrer">
<img src={user.avatar_url} alt="" style={{ width: 100 }} />
</a>
<p className="card-text">{user.login}</p>
</div>
)
}
子组件:src->components->Main.jsx
jsx
import React from 'react'
import PubSub from 'pubsub-js'
import { getUsers } from '../api/github'
import { useEffect,useState } from 'react'
import Item from './Item'
export default function Main() {
// 定义状态
let [users, setUsers] = useState([]) // 防止undefined
let [loading, setLoading] = useState(false);
let [first, setFirst] = useState(true);// 是否是第一次进入该页面
useEffect(()=>{
// 订阅消息
PubSub.subscribe('search',async (msg,data)=>{
// 判断first是否第一次
first && setFirst(false)
// 设置加载状态
setLoading(true)
// 发送请求,接收数据
console.log(data)
let {items} = await getUsers(data)
console.log(items)
// 设置数据状态
setUsers(items)
setLoading(false);
})
},[])
// 首次提示渲染
if (first) {
return <h4>请输入用户名搜索</h4>
}
// 加载中渲染
if (loading) {
return <h1>Loading.....</h1>
}
return (
<div className="row">
{users.map(user=>(
<Item user={user} key={user.id}/>
))}
</div>
)
}
封装axios实例:src->request->github.js
js
import axios from 'axios'
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'
const request = axios.create({
baseURL: 'https://api.github.com',
timeout: 2000
})
// 配置请求拦截器
request.interceptors.request.use(config => {
// 1. 请求头中携带公共参数 token
// 2. 开启loading效果
NProgress.start()
return config;
})
// 配置响应拦截器
request.interceptors.response.use(response => {
// 1. 关闭loading
NProgress.done()
// 2. 简化服务器数据
return response.data;
})
export default request; // 将配置好的axios暴露
封装api请求:src->api->github.js
js
/**
* 封装所有的github相关的请求函数
*
*/
import githubReq from '../request/github'
/**
*
* @param {*} keyword 关键字
* @param {*} sortType 排序方式
* @returns Promise对象
*
*/
export function getRepositories(keyword, sortType ='stars'){
return githubReq.get('/search/repositories',{
params: {
q: keyword,
sort: sortType
}
})
}
export function getUsers(username){
return githubReq.get('/search/users', {
params: {
q: username
}
})
}