YanTianFeng的知识库

Want Coding

Want Reading

文章 89

访问 18443

评论 2

头像

YanTianFeng

发私信

文章 89
访问 18443
评论 2
Technology and Code
返回顶部

Knowledge  Fetch总结

标签   fetch  

  ( 14 )       ( 0 )


Fetch 总结

说明

由于 Fetch API 是基于 Promise 设计,有必要先学习一下 Promise 。旧浏览器不支持 Promise ,需要使用 polyfill es6 - promise

如果不支持 fetch 也没有问题,可以使用第三方的 ployfill 来实现只会 fetch : whatwg - fetch 这个用的人多

发送一个 ajax 请求

XHR 方式

var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.responseType = 'json';
xhr.onload = function() {
  console.log(xhr.response);
};
xhr.onerror = function() {
  console.log("Oops, error");
};
xhr.send();

fetch 方式

fetch(url).then(function(res) {
    return res.json()
}).then(function(data) {
    console.log(data);
}).catch(function(e) {
    console.error(e)
})

fetch GET 请求初步

fetch(url, {
    method: 'GET'
})
.then((res) => {
    return res.text()
})
.then((res) => {
    console.log(res)
})

fetch GET 请求的参数传递

fetch(url + '?a=1&b=2', { // 在URL中写上传递的参数
    method: 'GET'
})
.then((res) => {
    return res.text()
})
.then((res) => {
    console.log(res)
})

fetch POST 请求初步

fetch(url, {
    method: 'POST' // 指定是POST请求
})
.then((res)=>{
    return res.text()
})
.then((res)=>{
    console.log(res)
})

fetch POST 请求参数的传递

let formData = new FormData()
formData.append('foo', 1)
formData.append('bar', 2)
fetch(url, {
    method: 'POST',
    body: formData,// 这里是请求对象
})
.then((res) => {
    return res.text()
})
.then((res) => {
    console.log(res)
})

fetch 设置请求的头信息

在 POST 提交的过程中,一般是表单提交,可是,经过查询,发现默认的提交方式是: Content - Type : text / plain ; charset = UTF - 8 ,这个显然是不合理的

fetch(url, {
    method: 'POST',
    headers: new Headers({
      'Content-Type': 'application/x-www-form-urlencoded' // 指定提交方式为表单提交
    }),
    body: new URLSearchParams([["foo", 1],["bar", 2]]).toString()
  })
  .then((res)=>{
    return res.text()
  })
  .then((res)=>{
    console.log(res)
  })

fetch 通过接口得到 JSON 数据

fetch(
    url, { // 在URL中写上传递的参数
        method: 'GET',
        headers: new Headers({
            'Accept': 'application/json' // 通过头指定,获取的数据类型是JSON
        })
    })
.then((res) => {
    return res.json() // 返回一个Promise,可以解析成JSON
})
.then((res) => {
    console.log(res) // 获取JSON数据
})

fetch 强制带 Cookie

默认情况下, fetch 不会从服务端发送或接收任何 cookies , 如果站点依赖于维护一个用户会话,则导致未经认证的请求 ( 要发送 cookies ,必须发送凭据头 )

fetch(url, {
    method: 'GET',
    credentials: 'include' // 强制加入凭据头
})

fetch 简单封装一下

/**
 * 将对象转成 a=1&b=2的形式
 * @param obj 对象
 */
function obj2String(obj, arr = [], idx = 0) {
  for (let item in obj) {
    arr[idx++] = [item, obj[item]]
  }
  return new URLSearchParams(arr).toString()
}

/**
 * 真正的请求
 * @param url 请求地址
 * @param options 请求参数
 * @param method 请求方式
 */
function commonFetcdh(url, options, method = 'GET') {
  const searchStr = obj2String(options)
  let initObj = {}
  if (method === 'GET') { // 如果是GET请求,拼接url
    url += '?' + searchStr
    initObj = {
      method: method,
      credentials: 'include'
    }
  } else {
    initObj = {
      method: method,
      credentials: 'include',
      headers: new Headers({
        'Accept': 'application/json',
        'Content-Type': 'application/x-www-form-urlencoded'
      }),
      body: searchStr
    }
  }
  fetch(url, initObj).then((res) => {
    return res.json()
  }).then((res) => {
    return res
  })
}

/**
 * GET请求
 * @param url 请求地址
 * @param options 请求参数
 */
function GET(url, options) {
  return commonFetcdh(url, options, 'GET')
}

/**
 * POST请求
 * @param url 请求地址
 * @param options 请求参数
 */
function POST(url, options) {
  return commonFetcdh(url, options, 'POST')
}
GET('https://www.baidu.com/search/error.html', {a:1,b:2})
POST('https://www.baidu.com/search/error.html', {a:1,b:2})

常见问题

1.Fetch 请求默认是不带 cookie 的,需要设置 fetch(url , { credentials : 'include' } )

2. 服务器返回 400 , 500 错误码时并不会 reject ,只有网络错误这些导致请求不能完成时, fetch 才会被 reject

3.Response 返回一个被解析后的 promise 对象和数据,有这些解析方式: arrayBuffer() 、 blob() 、、 json() 、 text() 、 formData()