前后端交互常见面试题——xhr、fetch

394 阅读3分钟

1. 介绍一下XMLHttpRequest对象

XMLHTTP对象是JS自带的一项用于异步请求的技术,可以在不刷新整个页面的情况下实现页面的局部刷新。Ajax是基于XMLHttpRequest对象封装而成的。

主流发送请求进行局部页面刷新内容的两个东西,一个是xhr,另一个是fetch。 也可以这样说,AJAX是对XMLHttpRequest的封装的一个统称,axios是对Ajax的封装。

xhr:

const ajax = new XMLHttpRequest() 0

ajax.open('sssxxxxx.com') 1

ajax.send() 2

接受数据 3 readyState onreadystateChange(res) { readyState === 3 && (console.log(res))| }

get请求

 // 创建XMLHttpRequest
 let xhr = new XMLRequest()
 ​
 // open方法获取接口
 xhr.open('GET', 'http:sssss')
 ​
 // 利用send发送AJAX请求
 xhr.send()
 ​
 // onreadystatechange函数监听
 xhr.onreadystatechange = function() {
     if(xhr.readyState === 4 || xhr.status === 200) {
         console.log(xhr.responseText)
     }
 }

post 请求

 // 创建XMLHttpRequest
 let xhr = new XMLRequest()
 ​
 // open方法获取接口
 xhr.open('GET', 'http:sssss')
 ​
 // 设置data格式Context-Type属性
 xhr.setRequestHeader('Context-type', 'application/x-www-form-urlencoded')
 ​
 // 利用send发送AJAX请求
 xhr.send()
 ​
 // onreadystatechange函数监听
 xhr.onreadystatechange = function() {
     if(xhr.readyState === 4 || xhr.status === 200) {
         console.log(xhr.responseText)
     }
 }

中止一个请求或者取消一个请求

  1. xhr

     var xhr= newXMLHttpRequest()
     xhr.abort()
    
  2. axios

 1. 使用 CancelToken.source 工厂方法创建cancel token
 const CancelToken = axios.CancelToken;
 const source = CancelToken.source();
 ​
 axios.get('/user/12345', {
   cancelToken: source.token
 }).catch(function(thrown) {
   if (axios.isCancel(thrown)) {
     console.log('Request canceled', thrown.message);
   } else {
      // 处理错误
   }
 });
 ​
 axios.post('/user/12345', {
   name: 'new name'
 }, {
   cancelToken: source.token
 })
 ​
 // 取消请求(message 参数是可选的)
 source.cancel('Operation canceled by the user.');
 ​
 2. 通过传递一个 executor 函数到 CancelToken 的构造函数创建cancel token
 const CancelToken = axios.CancelToken;
 let cancel;
 ​
 axios.get('/user/12345', {
   cancelToken: new CancelToken(function executor(c) {
     // executor 函数接收一个 cancel 函数作为参数
     cancel = c;
   })
 });
 ​
 // cancel the request
 cancel();.
 ​

取消一个异步请求有什么意义

  1. 已发出的请求可能仍然会到达后端。

  2. 取消后续的回调处理,避免多余的的回调处理,和一些特殊的情况,先发出的后返回,导致回调中的数据错误。

  3. 取消loading效果,以及该请求的其他交互的效果,一些单页面应用中,如果A页面跳转到B页面,A页面的请求应该取消,否则回调的函数有可能会影响到其他页面。

  4. 超时处理,错误处理等都省去了,可以节约资源

    取消请求的中介文章:t.zoukankan.com/skywind-p-1…

2. fetch

基础

Fetch和xhr一样,用于访问和操纵http请求,全局的fetch()方法

GET请求

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

POST请求

  fetch(url, {
     method: "POST",
     body: JSON.stringify(data),
   }).then(function(data) {
     console.log(data)
   }).catch(function(e) {
     console.log(e)
   })

参数

第1个参数:

指明资源路径的URL

第2个参数:

一个对象,可以配置不同配置的init对象

第二个参数对象的可选属性

  • method 请求使用的方法
  • headers 请求的头信息, Headers 对象或者ByteString 值的对象字面量。
  • body 请求的body信息 可以是一个可能是一个 BlobBufferSourceFormDataURLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
  • mode 请求模式cors,no-cors,same-origin
  • credentials
  • cache
  • redirect
  • 等等

返回值

一个Promise, resolved 时传回Response对象

取消请求

 // 声明AbortController
 const controller = new AbortController();
 ​
 // 正常的http调用
 fetch('https://jackniu81.github.io', { signal: controller.signal })
     .then(r => r.json())
     .then(response => {
         console.log(response);
     })
     .catch(err => {
         if (err.name === 'AbortError') {
             console.log('Fetch was aborted')
         } else {
             console.log('Error', err)
         }
     });
 ​
 // 需要取消请求时,调用:
 controller.abort()

取消请求

1. xhr

xhr.abort();

2. ajax

ajax.abort()

3. axios

axios.CancelToken

参考:juejin.cn/post/715383…

4. fetch

AbortController

参考:juejin.cn/post/684490…