ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[toc] ### Fetch Api概述 Fetch Api并非ES6语言标准范围内的内容,其属于HTML5新增的 Web Api,但由于其采用Promise方式,更利于异步代码的书写。因此将该方法放在异步处理后面进行学习。 **XMLHttpRequest的问题** 1. 所有的功能全部集中在同一个对象上,容易书写出混乱不易维护的代码 2. 采用传统的事件驱动模式,无法适配新的 Promise Api **Fetch Api 的特点** 1. Fetch Api并非取代 AJAX,而是对 AJAX 传统 API 的改进 2. 精细的功能分割:头部信息、请求信息、响应信息等均分布到不同的对象,更利于处理各种复杂的 AJAX 场景 3. 使用 Promise Api,更利于异步代码的书写 4. ### Fetch Api的用法 #### 基本使用 > 请求测试地址:http://101.120.82.37:5200/testapi/local (仅为书写,该地址不可用) 使用 ```fetch``` 函数即可立即向服务器发送网络请求 ```js // fetch的标准用法 const url = "http://101.120.82.37:5200/testapi/local"; const resp = await fetch(url) //当服务器有响应,获得其返回结果的Promise对象 const result = await resp.json(); //将服务器返回的Promise对象中的返回结果以json格式返回 console.log(result) ``` #### 参数 该函数有两个参数: 1. 必填,字符串,请求地址 2. 选填,对象,请求配置 **请求配置对象** - method:字符串,请求方法,默认值GET - headers:对象,请求头信息 - body: 请求体的内容,必须匹配请求头中的 Content-Type - mode:字符串,请求模式 - cors:默认值,配置为该值,会在请求头中加入 origin 和 referer - no-cors:配置为该值,不会在请求头中加入 origin 和 referer,跨域的时候可能会出现问题 - same-origin:指示请求必须在同一个域中发生,如果请求其他域,则会报错 - credentials: 如何携带凭据(cookie) - omit:默认值,不携带cookie - same-origin:请求同源地址时携带cookie - include:请求任何地址都携带cookie - cache:配置缓存模式 - default: 表示fetch请求之前将检查下http的缓存. - no-store: 表示fetch请求将完全忽略http缓存的存在. 这意味着请求之前将不再检查下http的缓存, 拿到响应后, 它也不会更新http缓存. - no-cache: 如果存在缓存, 那么fetch将发送一个条件查询request和一个正常的request, 拿到响应后, 它会更新http缓存. - reload: 表示fetch请求之前将忽略http缓存的存在, 但是请求拿到响应后, 它将主动更新http缓存. - force-cache: 表示fetch请求不顾一切的依赖缓存, 即使缓存过期了, 它依然从缓存中读取. 除非没有任何缓存, 那么它将发送一个正常的request. - only-if-cached: 表示fetch请求不顾一切的依赖缓存, 即使缓存过期了, 它依然从缓存中读取. 如果没有缓存, 它将抛出网络错误(该设置只在mode为”same-origin”时有效). #### 返回值 fetch 函数返回一个 Promise 对象 - 当收到服务器的返回结果后,Promise 进入resolved状态,状态数据为 Response 对象 - 当网络发生错误(或其他导致无法完成交互的错误)时,Promise 进入 rejected 状态,状态数据为错误信息 ### Request 对象 除了使用基本的fetch添加参数的方法,还可以通过创建一个Request对象做为参数传给fetch来完成请求(实际上,fetch的内部也会把传递进来的参数创建成一个Request对象) ```js new Request(url地址, 配置) ``` ```js //定义一个Request对象 function getRequest(){ let url = 'http://101.120.82.37:5200/testapi/local' let req = new Request(url, {}); return req } //发送fetch请求的时候可以这样写 let resp = fetch(getRequest()); //得到请求返回的Promise对象 let result = resp.json(); //用json格式获得请求返回的结果 console.log(result); ``` **注意** 尽量保证每次请求都是一个新的Request对象。如果定义好了一个Request对象,重新发送请求的时候Request对象中的数据并没有改变,但又想得到一个新的Request对象,可以使用Request对象的clone方法。 ```js function getRequest(){ let url = 'http://101.120.82.37:5200/testapi/local' let req = new Request(url, {}); return req.clone() } //这样每次就会获得一个新的Request对象 ``` ### Response 对象 Response对象是fetch发送请求后,Promise对象返回resolve结果时的对象。该对象通常为返回时自动创建。 该对象的基本属性如下: - ok:boolean,当响应消息码在200~299之间时为true,其他为false - status:number,响应的状态码 - text():用于处理文本格式的 Ajax 响应。它从响应中获取文本流,将其读完,然后返回一个被解决为 string 对象的 Promise。 - blob():用于处理二进制文件格式(比如图片或者电子表格)的 Ajax 响应。它读取文件的原始数据,一旦读取完整个文件,就返回一个被解决为 blob 对象的 Promise。 - json():用于处理 JSON 格式的 Ajax 的响应。它将 JSON 数据流转换为一个被解决为 JavaScript 对象的promise。 - redirect():可以用于重定向到另一个 URL。它会创建一个新的 Promise,以解决来自重定向的 URL 的响应。 Response对象也可以手动创建,用于模拟服务器返回的数据。平时很少使用 ```js const resp = new Response(`[ {'id': 0, 'name': '小张'}, {'id': 1, 'name': '小刘'}, ]`, //第一个参数用来写json格式的数据体,可以使用模版字符来创建 { ok: true, status: 200, } //第二个参数用来设置Response对象中的相关属性 ) ``` ### Headers 对象 在Request和Response对象内部,会将传递的请求头对象,转换为一个Headers对象 开发过程中,通常请求头中的数据基本不变,可以声明一个Headers对象,省去每次发送请求时都要重复填写请求头内容。 ```js const header = new Headers({ title: '标题', content: '内容' }) //这样就创建了一个请求头对象,结合上面的Request对象,发送请求的时候参数可以直接填写两个对象名即可 const resp = fetch(getRequest(), header) //这种方式可以更加的节省代码的重复书写 ``` 获取返回数据中的Headers对象: ```js const result = resp.headers ``` Headers对象中的方法: - has(key):检查请求头中是否存在指定的key值 - get(key): 得到请求头中对应的key值 - set(key, value):修改对应的键值对 - append(key, value):添加对应的键值对 - keys(): 得到所有的请求头键的集合 - values(): 得到所有的请求头中的值的集合 - entries(): 得到所有请求头中的键值对的集合 ### 文件上传 流程: 1. 客户端将文件数据发送给服务器 2. 服务器保存上传的文件数据到服务器端 3. 服务器响应给客户端一个文件访问地址 > 测试地址:http://101.120.82.37:5200/testapi/local > 键的名称(表单域名称):imagefile 请求方法:POST 请求的表单格式:multipart/form-data 请求体中必须包含一个键值对,键的名称是服务器要求的名称,值是文件数据 > HTML5中,JS仍然无法随意的获取文件数据,但是可以获取到input元素中,被用户选中的文件数据 > 可以利用HTML5提供的FormData构造函数来创建请求体