【Js】fetch网络请求

一、网络请求方式:

  1. AJAX:基于XMLHttpRequest收发请求,使用较为繁琐,代码量会比较多
  2. axios:基于promise的请求客户端,在浏览器和node中均可使用,使用便捷,功能强大
  3. fetch:内置api,基于promise,用法和axios类似,功能更为简单,没有axios那么强大

ajax一般为学习过渡使用,日常开发中一般不会使用。做项目的时候一般是使用axios,当项目规模比较小,调用接口次数很少的时候可以使用 fetch 替换 axios ,这样更为便捷迅速。

二、fetch介绍 

该fetch介绍转自:前端人博客

1.1、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
  • headers - http请求头设置
  • keepalive - 用于页面卸载时,告诉浏览器在后台保持连接,继续发送数据。
  • credentials - cookie设置,默认omit,忽略不带cookie,same-origin同源请求带cookie,inclue无论跨域还是同源都会带cookie。

1.2、response 对象

fetch 请求成功后,响应 response 对象如图:

【Js】fetch网络请求_第1张图片

  • status - http状态码,范围在100-599之间
  • statusText - 服务器返回状态文字描述
  • ok - 返回布尔值,如果状态码2开头的,则true,反之false
  • headers - 响应头
  • body - 响应体。响应体内的数据,根据类型各自处理。
  • type - 返回请求类型。
  • redirected - 返回布尔值,表示是否发生过跳转。

1.3、读取内容方法

response 对象根据服务器返回的不同类型数据,提供了不同的读取方法。分别有:

  1. response.text() -- 得到文本字符串
  2. response.json() - 得到 json 对象
  3. response.blob() - 得到二进制 blob 对象
  4. response.formData() - 得到 fromData 表单对象
  5. response.arrayBuffer() - 得到二进制 arrayBuffer 对象

上述 5 个方法,返回的都是 promise 对象,必须等到异步操作结束,才能得到服务器返回的完整数据。

1.4、response.clone()

stream 对象只能读取一次,读取完就没了,这意味着,上边的五种读取方法,只能使用一个,否则会报错。

因此 response 对象提供了 clone() 方法,创建 respons 对象副本,实现多次读取。如下:将一张图片,读取两次:

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);

1.5、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() 方法每次都会返回一个对象,表示本次读取的内容块。

三、异步请求

fetch方法用于发起获取资源的请求,它返回一个promise,这个promise会在请求响应后被resolve,并传回request对象。fetch不支持同步请求,这意味着你不能像使用 XMLHttpRequest 那样直接在代码中执行同步请求。

fetch返回的数据不是即时的,因为加载 URL 并将其取回需要时间。如果我们单独运行 Fetch,控制台日志将返回一个 Promise,而不是我们想要的接口返回的响应:

// 假设后端接口为:https://www.example.com/api/get_user_info
// 该接口返回的数据为:{name:'张三',sex:'女',age:25}

let apiResponse = fetch("https://www.example.com/api/get_user_info");
console.log(apiResponse); // 打印结果:Promise1.2.3.

在fetch() 函数运行时,JavaScript并不会等待响应。如果我们想要访问响应,我们必须明确告诉 JavaScript 需要等待。

等待 fetch() 有两种方法:

  • 可以在 then 循环中使用 then 并操作 fetch() 的响应。
  • 可以使用 await,并在使用其内容之前等待 Fetch 返回。

 在 JavaScript 中使用 Then 等待 Fetch

从fetch()调用中访问数据的一种方法是将其链接到Fetch上,从而允许我们从URL访问响应。fetch()的内容可以在then()回调函数内操作。

fetch('https://www.example.com/api/get_user_info')
  .then(response => {
    if (!response.ok) {
      throw new Error('Network response was not ok');
    }
    return response.json(); // 将响应解析为 JSON 格式
  })
  .then(data => {
    // 处理返回的数据
    console.log(data);//打印结果:json数据{name:'张三',sex:'女',age:25}
  })
  .catch(error => {
    // 处理错误
    console.error('There was a problem with the fetch operation:', error);
  });

fetch()的内容可以在then()回调函数内操作,但不能在回调函数外操作。

let apiResponse = fetch("https://www.example.com/api/get_user_info")
    .then(res => res.json())
    .then((data) => {
      //在这里处理数据是没问题的
      console.log(data); //打印结果:json数据{name:'张三',sex:'女',age:25}
      return data;
    });
console.log(apiResponse); //打印结果:Promise

如果我们想在 then 函数之外使用 fetch() 的内容,则必须使用 await。

async function getAPI() {
  let apiResponse = await fetch("https://www.example.com/api/get_user_info");
  let response = await apiResponse.json(); //如果不用await,最终打印结果也会是:Promise
  console.log(response); //打印结果:json数据{name:'张三',sex:'女',age:25}
}

getAPI();

post提交

// form表单提交
fetch(`https://www.exaplem.com/api/save_user_info`,{
  method:'POST',
  headers:{
    'Content-Type':'application/x-www-form-urlencoded;charset=UTF-8',
    'Authorization': `Token ${login.token}`
  },
  body:`name=${user.name}&sex=${user.sex}&age=${user.age}`
}).then(response=>{
  console.log('响应',response)
})

// 如果是提交json数据时,需要把json转换成字符串。如
// body:JSON.stringify(json)
// 如果提交的是表单数据,使用 formData转化下,如:
// body:new FormData(form)

// 上传文件,可以包含在整个表单里一起提交,如:
// const data = new FormData();
// data.append('file', input.files[0]);
// data.append('user', 'foo');
// body:new FormData(form)

// 上传二进制数据,将 bolb 或 arrayBuffer 数据放到body属性里,如:
let blob = await new Promise(resolve =>   
  canvasElem.toBlob(resolve,  'image/png')
);

let response = await fetch('https://www.exaplem.com/api/save_user_portrait', {
  method:'POST',
  body:blob
});

四、注意事项

1、 fetch默认不带cookie

传递cookie时,必须在header参数内加上 credentials:'include',才会像 xhr 将当前cookie 带有请求中。

2、异常处理

fetch 不同于 xhr ,xhr 自带取消、错误等方法,所以服务器返回 4xx 或 5xx 时,是不会抛出错误的,需要手动处理,通过 response 中的 status 字段来判断

你可能感兴趣的:(javascript,javascript,开发语言,ecmascript)