fetch介绍
fetch()是一个全局方法,提供一种简单,合理的方式跨网络获取资源。它的请求是基于Promise
fetch使用语法
fetch(url,options).then((response)=>{
//处理http响应
},(error)=>{
//处理错误
})
url:是发送网络请求的地址
options:发送请求参数
- body: http请求参数
- mode: 指定请求模式。默认值为cros:允许跨域;same-origin:只允许同源请求;
no-cros:只限于get、post和head,并且只能使用有限的几个简单标头。
- cache: 用户指定缓存
- method:请求方法,默认GET
- signal:用于取消fetch
- header:http请求头设置
- keepalive:用于页面卸载时,告诉浏览器后台保持连接,继续发送数据
- credentials:cookie设置,默认omit,忽略不带cookie,same-origin同源请求
带cookie,inclue无论跨域还是同源都会带cookie
response对象
fetch 请求成功后,响应response对象如图:
status:http状态码,范围在100-599之间
statusText:服务器返回状态文字描述
ok:返回布尔值,如果状态码2开头的,则返回true,反之false
headers:响应头
body:响应体
type:返回请求类型
redirected:返回布尔值,表示是否发生过跳转
读取内容方法
response对象根据服务器返回的不同类型数据,提供了不同的读取方法。分别有:
- response.text():得到文本字符串
- response.json():得到json对象
- respnse.blob():得到二进制blob对象
- response.formData():得到fromData表单对象
- response.arrayBuffer():得到二进制arrayBuffer对象
response.clone()
stream 对象只能读取一次,读取完就没了,这意味着,上边的五种读取方法,只能使用一个,否则会报错。因此response对象提供了 clone()方法,创建rsponse对象副本,实现多次读取。如:将一张图片,读取两次:
const response1 = await fetch('flowers.jpg');
const response2 = response1.clone();
const myBlob1 = await response1.blob();
const myBlob2 = await response2.blob();
image1.src = URL.createObjectURL(myBlob1);
image2.src = URL.createObjectURL(myBlob2);
response.body()
body属性返回一个ReadableStream对象,供用户操作,可以用来分块读取内容,显示下载的进度就是其中一种应用
const response = await fetch('flower.jpg');
const reader = response.body.getReader();
while(true) {
const {done, value} = await reader.read();
if (done) {
break;
}
console.log(`Received ${value.length} bytes`)
}
response.body.getReader()返回一个遍历器,这个遍历器read()方法每次都会返回一个对象,表示本次读取的内容块
不同请求如何处理
请求方式不同,传值方式也不同。xhr会分别处理get和post数据传输,还有请求头设置,同样fetch也需要分别处理。
get方式:(只需要在url中加入传输数据,options中加入请求方式)
<input type="text" id="user"><br>
<input type="password" id="pas"><br>
<button onclick="login()">提交</button>
<script>
function login(){
fetch(`http://localhost:80/fetch.html?user=${user.value}&pas=${pas.value}`,{
method:'GET'
}).then(response=>{
console.log('响应',response)
})
}
</script>
post方式:(使用post发送请求时,需要设置请求头、请求数据等)
fetch(`http://localhost:80/ES6练习题/53fetch.html`,{
method:'POST',
headers:{
'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8'
},
body:`user=${user.value}&pas=${pas.value}`
}).then(response=>{
console.log('响应',response)
})
如果是提交json数据时,需要把json转换成字符串:
body:JSON.stringify(json)
如果提交的是表单数据,使用formData转化:
body:new FormData(form)
上传文件,可以包含在整个表单里一起提交:
const input = document.querySelector('input[type="file"]');
const data = new FormData();
data.append('file', input.files[0]);
data.append('user', 'foo');
fetch('/avatars', {
method: 'POST',
body: data
});
上传二进制数据,将blob或arrayBuffer数据放到body属性里:
let blob = await new Promise(resolve =>
canvasElem.toBlob(resolve, 'image/png')
);
let response = await fetch('/article/fetch/post/image', {
method: 'POST',
body: blob
});
fetch常见坑:
- 兼容性不好
- 默认不带cookie,传cookie时,必须在header参数内加上credenials:'include',才会像 xhr将cookie带请求头中
- 异常处理需要手动实现