fetch的使用
fetch接收一个URL字符串作为参数,默认向该url地址发出GET请求,返回一个Promise对象。
fetch('http://localhost:9527/upload/single').then().catch()
简单的实际例子
promise风格写法
fetch('https://api.github.com/users/ccf-666').then(res=>res.json()).then(body=>{
console.log(body);
}).catch(err=>console.log(err));
上面示例中,fetch接收到的res是一个Stream对象,这意味着前端不用等到收到所有数据后才开始处理数据,而是可以收到一点处理一点(后面有例子说明)
async/await的写法
async function readData(){
try{
const res=await fetch('https://api.github.com/users/ccf-666');
cosnt resData=await res.json();
console.log(resData);
}catch(err){
console.log(err)
}
}
Response对象
从上的例子可以看到,fetch要经过两次then/await才能拿到数据。第一次then/await,fetch接收到响应头,此时可以直接通过返回的Respone对象获取相应的响应头信息。
cosnt res=await fetch('https://api.github.com/users/ccf-666');
//第一个属性 返回一个布尔值,表示请求是否成功
res.ok
//第二个属性 返回一个数字,表示HTTP响应的状态码(200)
res.status
//第三个属性 返回一个字符串,表示HTTP响应的状态信息('OK')
res.statusText
//第四个属性 返回一个请求的url
res.url
//第五个属性 返回一个字符串,代表请求的类型
// basic 代表同源请求 cors 代表跨域请求
//error 代表网络错误 还有其他类型
//第六个属性 返回一个布尔值,代表请求是否发生跳转
res.redirected
判断请求是否成功
fetch发出请求后,只有网络错误或者无法连接时,才会发生报错,其他情况不会发生报错,而是认定为成功。即使返回的状态码为4xx或5xx,fetch返回的Promise的状态也会变为Fulfilled
所以,需要通过Response.status/ok来判定请求是否成功。
//第一种
fetch('https://api.github.com/users/ccf-666').then(res=>{
if(res.status>=200&&res.status<300)
{
return res.json();
}else{
throw new Error(res.statusText);
}
}).then(body=>{
console.log(body)
}).catch(err=>{
console.log(err)
})
//第二种
if(res.ok)
{
return res.json();
}else{
throw new Error(res.statusText);
}
headers属性
Response对象还有一个headers属性,是一个Headers对象,代表着所有响应头信息。
Response读取数据的方法
res.json() 得到响应数据的json格式
res.text() 得到响应数据的文本字符串
res.blob() 得到响应数据的二进制 Blod对象
res.formData() 得到响应数据的FormData表单格式
clone方法
前面说到,fetch返回的res 是一个Stream对象,所以它只能读取一次,读完就不能再次读取。
let data1=await res.json();
let data2=await res.text();//发生报错
因此,有了clone这个方法,来创建res的副本。
const res=await fetch('https://api.github.com/users/ccf-666');
cosnt res2= res.clone();
let data1=await res.json();
let data2=await res2.text();//不发生报错
body属性
既然fetch返回的res是一个Stream对象,那么res可以一点一点获取,不用等到接收到所有数据才完成响应。Response.body属性就是用来实现这一点的,它是一个ReadableStream (可读流对象)。
const res=await fetch('xxx');
//获取流读取器
const reader =res.body.getReader();
while(true){
cosnt {done,value}=await reader.read();
if(done){
break;
}
console.log(`每次接收到的数据:${value}`);
}
getReader()返回的是
ReadableStreamDefaultReader 可读流对象读取器 解析流的对象。reader.read()就是接收/读取流数据,所以是一个异步操作,每次读取器接收数据返回的有done和value,done表示是否所有数据是否读完了(fasle/true) value就是接收到的数据,它是一个Uint8Array。这个需要使用TextDecoder()进行解码才能获取到文本。
const decoder=new TextDecoder();
while(true){
const {done,value}=await reader.read();
// console.log(done);
// console.log(value);
if(done){
break;
}
const txt=decoder.decode(value);
console.log(txt);
}
定制HTTP请求
配置对象
fetch()的第一个参数是URL,第二个参数是配置对象,可以设置请求方法,请求头,请求体
const res=await fetch(url,{
method:'POST',
headers:{
'Content-type':'application/json'
},
body:JSON.stringify({
"loginId":"admin1",
"loginPwd":"123123"
})
})
// console.log(res);
const body=await res.json();
console.log(body);
(先了解一下)配置对象有很多,下面是完整的:
取消请求
fetch请求发送后,如果想要取消,可以使用AbortController对象
const controller=new AbortController();
//1s后调用abort方法 取消请求
setTimeout(()=>controller.abort(),1000);
try{
const res=await fetch(url,{
signal:controller.signal
})
}catch(err){
console.log(err);
}
想要中途取消请求,需要给signal属性配置一个 controller.signal。 想要取消时,就要调用controller.abort()