Fetch API用法示例

本文介绍fetch函数的几个常用用法。

本文中所有示例均可在https://www.lyz810.com/demo/fetch/中查看演示

实例一、最简单的发送GET请求,返回文本数据
fetch会返回一个promise,可以使用then的第一个函数接收响应对象(Response对象)

function func1(){
  fetch('./api.php?action=getPlain')
   .then(function (response){
    //text方法将响应转为纯文本
    return response.text();
   })
   .then(function (text){
    alert(text);
   });
 }

实例二、发送GET请求,带自定义头,返回json数据
fetch的第二个参数为一个Request对象,headers为请求头的参数,例子中添加了一个自定义的请求头userHeader,值为myHeader

function func2(){
  fetch('./api.php?action=getJson',{
   headers:{
    userHeader:'myHeader'
   }
  })
   .then(function (response){
    //json方法将响应转为json对象
    return response.json();
   })
   .then(function (json){
    alert(JSON.stringify(json));
   });
 }

实例三、发送POST请求,通过Request类及Header类,返回json数据
可以直接通过Request类和Header作为fetch的参数

function func3(){
  var headers = new Headers();
  headers.set('userHeader', 'myHeader');
  headers.append('Content-type','application/x-www-form-urlencoded');
  var request = new Request('./api.php?action=getJson',{
   headers: headers,
   method: 'POST'
  });
  fetch(request)
   .then(function (response){
    return response.json();
   })
   .then(function (json){
    alert(JSON.stringify(json));
   });
 }

实例四、发送HEAD请求,只获取响应头的信息
发送HEAD请求,通过response对象的headers属性的get方法可以获取响应头信息

function func4(){
  fetch('./api.php?action=getPlain',{
   method: 'HEAD'
  })
   .then(function (response){
    alert(response.headers.get('Response-key'))
   });
 }

实例五、带cookie发送POST请求,包含请求体
默认情况下,fetch不会带着cookie,必须使用credentials: ‘include’参数才可以使请求带上cookie

function func5(){
  fetch('./api.php?action=getJson', {
   method: 'POST',
   credentials: 'include',
   headers:{
    'Content-Type': 'application/x-www-form-urlencoded'
   },
   body: 'test=test'
  })
   .then(function (response){
    return response.json();
   })
   .then(function (data){
    alert(JSON.stringify(data));
   });
 }

实例六、POST请求,body内容为formData
body的内容不仅支持字符串还支持formData、Blob等类型

function func6(){
  //这种方式可以用来提交表单,上传文件等
  var formData = new FormData();
  formData.set('key', 'value');
  fetch('./api.php?action=getJson', {
   method: 'POST',
   headers:{
    'userHeader': 'This is my header!'
   },
   credentials: 'include',
   body: formData
  })
   .then(function (response){
    return response.json();
   })
   .then(function (data){
    alert(JSON.stringify(data));
   });
 }

Fetch API介绍

本文介绍Fetch API的基础概念,参考自fetch.spec.whatwg.org

fetch()是相对低级的获取资源的API。它比XMLHttpRequest覆盖面稍微广一些。
示例:

fetch()方法很明确是获取一个资源,然后提取它的内容为Blob类型:

fetch("/music/pk/altes-kamuffel.flac")
  .then(res => res.blob()).then(playBlob)

如果你只是关心记录响应头:
fetch("/", {method:"HEAD"})
  .then(res => log(res.headers.get("strict-transport-security")))

如果你想要检查一个特别的响应头,然后处理跨域资源的响应:
fetch("https://pk.example/berlin-calling.json", {mode:"cors"})
  .then(res => {
    if(res.headers.get("content-type") &&
       res.headers.get("content-type").toLowerCase().indexOf("application/json") >= 0) {
      return res.json()
    } else {
      throw new TypeError()
    }
  }).then(processJSON)

如果你想要使用URL查询参数:
var url = new URL("https://geo.example.org/api"),
    params = {lat:35.696233, long:139.570431}
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
fetch(url).then(/* … */)

如果你想要逐步的收到数据:
function consume(reader) {
  var total = 0
  return pump()
  function pump() {
    return reader.read().then(({done, value}) => {
      if (done) {
        return
      }
      total += value.byteLength
      log(`received ${value.byteLength} bytes (${total} bytes in total)`)
      return pump()
    })
  }
}

fetch("/music/pk/altes-kamuffel.flac")
  .then(res => consume(res.body.getReader()))
  .then(() => log("consumed the entire body without keeping the whole thing in memory!"))
  .catch(e => log("something went wrong: " + e))

Headers类
Headers对象有一个头部列表,初始化为空。
Headers对象也有一个guard,值为“immutable”、“request”、“request-no-cors”、“response”或“none”。
提示:“immutable”为server workers而存在。

Headers类包含以下方法:
append(name, value):向Headers对象中添加请求头键值对
delete(name):从Headers对象中删除某个名称
get(name):从Headers对象中获取某个名称
has(name):判断Headers对象中是否存在某个名称
set(name, value):设置Headers对象的某个键值对

Body混合类型
body支持以下数据类型:
arrayBuffer、blob、formData、json、text

Request类
Request类包含以下属性:
method:请求方法

url:请求URL

headers:相关联的Headers对象

type:请求类型(空字符串, “audio”, “font”, “image”, “script”, “style”, “track”, 或”video”)

Destination:请求目标(空字符串, “document”, “embed”, “font”, “image”, “manifest”, “media”, “object”, “report”, “script”, “serviceworker”, “sharedworker”, “style”, “worker”, 或 “xslt”)

referrer:请求来源

referrerPolicy:referrer策略

mode:请求模式(”same-origin”, “cors”, “no-cors”, “navigate”,或 “websocket”)

credentials:认证模式(”omit”, “same-origin”, 或”include”)

cache:缓存模式(”default”, “no-store”, “reload”, “no-cache”, “force-cache”, 或”only-if-cached”)

redirect:重定向模式(”follow”, “error”,或 “manual”)

integrity:完整的数据类型

方法:
clone():克隆Request对象

Response类
属性:
type:响应类型(”basic”, “cors”, “default”, “error”, “opaque”, 或”opaqueredirect”)

url:排除fragment部分的url

redirected:重定向的url列表

status:http状态码

ok:状态码为200~299,否则为false

statusText:状态文本信息

headers:包含头部信息的Headers对象

body:相关联的响应体内容

方法:
clone():克隆Response对象

垃圾回收

示例:

用户代理可以终止fetch,由于它不能被引用:
fetch("https://www.example.com/")


用户代理不能终止fetch,由于它被promise引用:
window.promise = fetch("https://www.example.com/")

用户代理可以终止fetch,因为相关的body不能观测到:
window.promise = fetch("https://www.example.com/").then(res => res.headers)


用户代理可以终止fetch,因为结果不可见:
fetch("https://www.example.com/").then(res => res.body.getReader().closed)

用户代理不能终止fetch,因为可以通过注册一个处理器来得到结果(被promise变量引用):
window.promise = fetch("https://www.example.com/")
  .then(res => res.body.getReader().closed)

用户代理不能终止fetch,因为结果会通过注册的处理器获取:
fetch("https://www.example.com/")
  .then(res => {
    res.body.getReader().closed.then(() => console.log("stream closed!"))
  })