首页 > javascript学习 > JavaScript > Fetch入门介绍
2021
04-23

Fetch入门介绍

fetch是一种在JavaScript脚本里面发出HTTP请求的方式,是XMLHttpRequest的一种替代方案。

fetch不是ajax的进一步封装,而是原生js,没有使用XMLHttpRequest对象。

fetch和XMLHttpRequest的不同点:

1、fetch使用了Promise,不使用回调函数,大大简化了写法;
2、fetch返回的promise将不会拒绝http的错误状态,即使响应是一个HTTP404或者500;
3、在默认情况下fetch不会接受或者发送cookies;
4、fetch采用模块化设计,API分散在多个对象上(Response、Request、Headers、ReadableStream等),更合理;
5、fetch通过数据流(Stream对象)异步处理数据,可以分块读取,有利于提高网站性能表现,减少内存占用,对于请求大文件或者网速慢的场景相当有用。

fetch语法:fetch(url,option_obj)

option_obj是一个object对象,HTTP请求的方法、标头、数据体都在这个对象里面设置

    method:请求的方法(string),可选值GET/POST/DELETE/PUT/HEAD等,默认GET
    headers:请求标头(object),每个键值对为一个表头项目
    body:请求的数据体
    cache: 指定如何处理缓存,可能的值
        default:默认值,先在缓存里面寻找匹配的请求
        no-store:直接请求远程服务器,并且不更新缓存
        reload:直接请求远程服务器,并且更新缓存
        no-cache:将服务器资源跟本地缓存进行比较,有新的版本才使用服务器资源,否则使用缓存
        force-cache:缓存优先,只有不存在缓存的情况下,才请求远程服务器
        only-if-cached:只检查缓存,如果缓存里面不存在,将返回504错误
    mode: 指定请求的模式,可能的值
        cors:默认值,允许跨域请求
        same-origin:只允许同源请求
        no-cors:只限于GET、POST和HEAD方法,且只能使用有限的几个简单标头,不能添加跨域的复杂标头,相当于提交表单所能发出的请求。
        跨源请求时,返回的表头中必须要有Access-Control-Allow-Origin表头,表示服务于允许跨域请求的域名(格式:http[s]://domain),星号表示允许所有,但是设置为星号会导致浏览器不发送cookies
        请求表头中添加上Origin表头,指定请求的域名
    credentials: 是否发送cookies,可能的值
        same-origin:默认值,同源请求时发送Cookie,跨域时不发送
        include:一律发送Cookie
        omit:一律不发送
    signal:指定一个 AbortSignal 实例,用于取消fetch()请求
    keepalive:布尔值,页面卸载时浏览器是否在后台保持连接,继续发送数据
    redirect: 指定 HTTP 跳转的处理方法,可能的值
        follow:默认值,跟随HTTP跳转。
        error:如果发生跳转,就报错
        manual:不跟随HTTP跳转,但response.url属性会指向新的URL,response.redirected属性会变为true
    integrity:指定一个哈希值,用于检查HTTP回应传回的数据是否等于这个预先设定的哈希值
        integrity: 'sha256-abcdef'
    referrer:设定来源网址
    referrerPolicy:用于设定Referer标头的规则
        no-referrer-when-downgrade:默认值,除从HTTPS页面请求HTTP时不发送,其他一律发送
        no-referrer:一律不发送
        origin:标头只包含域名,不包含完整的路径。
        origin-when-cross-origin:同源请求包含完整的路径,跨域请求只包含域名
        same-origin:跨域请求不发送,同源请求发送。
        strict-origin:只包含域名,HTTPS页面请求HTTP时不发送
    strict-origin-when-cross-origin:同源时包含完整路径,跨域时只包含域名,HTTPS页面请求 HTTP资源时不发送
    unsafe-url:不管什么情况,总是发送Referer标头

在请求过程中中断请求

fetch()请求发送以后,如果中途想要取消,需要使用AbortController对象

//1、在fetch()请求之前创建一个AbortController对象
let controller = new AbortController();
//2、创建一个信号接收对象:signal对象
let signal = controller.signal;
//3、把该信号接收对象通过signal属性传递到fetch()请求中
fetch(url, {
  signal: controller.signal
});

//接收信号对象接收取消信号后会触发abort事件
signal.addEventListener('abort',
  () => console.log('abort!')
);

//4、AbortController对象的abort()方法发出取消信号
controller.abort(); // 取消

//发出取消信号后信号接收对象的aborted属性可以判断取消信号是否接收
console.log(signal.aborted); // true

fetch函数返回Response对象

Response对象的属性:

ok:布尔值,true对应HTTP状态码200到299,false对应其他的状态码
status:数字,表示HTTP状态码(3XX跳转状态码会自动转为200)
statusText:字符串,表示HTTP回应的状态码字符串信息。
url:请求的URL,如果存在跳转,返回的是最终URL
type属性返回请求的类型。可能的值如下:
    basic:普通请求,即同源请求。
    cors:跨域请求。
    error:网络错误,主要用于Service Worker。
    opaque:如果fetch()请求的type属性设为no-cors,就会返回这个值。
        表示发出的是简单的跨域请求,类似
表单的那种跨域请求。 opaqueredirect:如果fetch()请求的redirect属性设为manual,就会返回这个值。 redirected:布尔值,表示请求是否发生过跳转

Response对象的方法:

    text():得到文本字符串
    json():得到 JSON 对象
    blob():得到二进制Blob对象
    formData():得到FormData表单对象
    arrayBuffer():得到二进制ArrayBuffer对象
    以上5个读取方法都是异步的,返回的都是Promise对象。
    必须等到异步操作结束,才能得到服务器返回的完整数据。
    而且5种方法一共只能使用一次,多次使用获取数据(即使不是一个方法)会报错
        clone()可以创建一个Response对象副本(副本也只能读取一次),可以创建多个副本达到多次读取的目的
    redirect():用于将Response结果重定向到指定的URL(一般用在Service Worker里面)

Response.headers指向一个Headers对象,对应HTTP回应的所有标头:

get(key):根据指定的标头名,返回对应的标头值
has(key): 返回一个布尔值,表示是否包含某个标头
set(key,value):将指定的标头设置为新的值,如果标头名不存在则会添加
append(key,value):添加标头
delete(key):删除标头
keys():返回一个遍历器,可以依次遍历所有标头名
values():返回一个遍历器,可以依次遍历所有标头值
entries():返回一个遍历器,可以依次遍历所有键值对([key, value])
forEach():依次遍历标头,每个标头都会执行一次参数函数

Response.body指向一个ReadableStream对象,可以用来分块读取内容

const response = await fetch('/test/down/notapad2.7z');
const reader = response.body.getReader();
let size=0;
while(true) {
    //这个对象的done属性是一个布尔值,用来判断有没有读完;
    //value属性是一个 arrayBuffer 数组,表示当前内容块的内容
    const {done, value} = await reader.read();
    if (done) {break;}
    size=size+value.length;
    console.log(`本次接收 ${value.length/1024} kb`)
}
console.log(`共计下载${size/1024}kb,${size/1024/1024}mb`)
最后编辑:
作者:qingheluo
这个作者貌似有点懒,什么都没有留下。

留下一个回复

你的email不会被公开。