fetch ajax 请求相关

498 阅读4分钟

什么是fetch

fetch是一种HTTP数据请求的方式,是XMLHttpRequest的一种替代方案。fetch不是ajax的进一步封装,而是原生js。Fetch函数就是原生js,没有使用XMLHttpRequest对象。 window自带了window.fetch()方法

fetch发送post请求的时候总是发送2次,第一次状态码是204,第二次才成功?

是因为用fetch的post请求时,导致fetch第一次发送了一个Options请求,询问服务器是否支持修改的请求头,如果服务器支持,则在第二次中发送真正的请求。

一个基本的fetch请求

fetch('http://example.com/movies.json')
  .then(function(response) {
    return response.json();
  })
  .then(function(myJson) {
    console.log(myJson);
  });

fetch() 接受第二个可选参数,一个可以控制不同配置的 init 对象

// Example POST method implementation:

postData('http://example.com/answer', {answer: 42})
  .then(data => console.log(data)) // JSON from `response.json()` call
  .catch(error => console.error(error))

function postData(url, data) {
  // Default options are marked with *
  return fetch(url, {
    body: JSON.stringify(data), // must match 'Content-Type' header
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, same-origin, *omit
    headers: {
      'user-agent': 'Mozilla/4.0 MDN Example',
      'content-type': 'application/json'
    },
    method: 'POST', // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, cors, *same-origin
    redirect: 'follow', // manual, *follow, error
    referrer: 'no-referrer', // *client, no-referrer
  })
  .then(response => response.json()) // parses response to JSON
}

发送带凭据的请求

为了让浏览器发送包含凭据的请求(即使是跨域源),要将credentials: 'include'添加到传递给 fetch()方法的init对象。

fetch('https://example.com', {
  credentials: 'include'  
})

如果你只想在请求URL与调用脚本位于同一起源处时发送凭据,请添加 credentials: 'same-origin'。

fetch('https://example.com', {
  credentials: 'same-origin'  
})

要改为确保浏览器不在请求中包含凭据,请使用 credentials: 'omit'。

fetch('https://example.com', {
  credentials: 'omit'  
})

fetch请求的取消

AbortController 接口代表一个控制器对象,允许你在需要时中止一个或多个DOM请求。

AbortController.signal 属性(只读)返回一个AbortSignal对象实例,它可以用来 with/abort 一个DOM请求。

AbortController.abort()方法 中止一个尚未完成的DOM请求。这能够中止fetch 请求,任何响应Body的消费者和流。

直接看下面的栗子:

var controller = new AbortController();
var signal = controller.signal;

var downloadBtn = document.querySelector('.download');
var abortBtn = document.querySelector('.abort');

downloadBtn.addEventListener('click', fetchVideo);

abortBtn.addEventListener('click', function() {
  controller.abort();
  console.log('Download aborted');
});

function fetchVideo() {
  ...
  fetch(url, {signal}).then(function(response) {
    ...
  }).catch(function(e) {
    reports.textContent = 'Download error: ' + e.message;
  })
}

注意: 当abort() 被调用,fetch() promise rejects 一个 AbortError。

什么是ajax

AJAX是异步的JavaScript和XML(Asynchronous JavaScript And XML)。 简单点说,就是使用 XMLHttpRequest 对象与服务器通信。 它可以使用JSON,XML,HTML和text文本等格式发送和接收数据。 AJAX最吸引人的就是它的“异步”特性,也就是说他可以在不重新刷新页面的情况下与服务器通信,交换数据,或更新页面。

怎么样发送http请求

为了使用JavaScript向服务器发送一个http请求,你需要一个包含必要函数功能的对象实例。这就是为什么会有 XMLHttpRequest 的原因。

  1. 创建ajax对象
// Old compatibility code, no longer needed.
if (window.XMLHttpRequest) { // Mozilla, Safari, IE7+ ...
    httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE 6 and older
    httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
  1. 设置对象的 onreadystatechange 属性后给他命名,当请求状态改变时调用函数。
httpRequest.onreadystatechange = nameOfTheFunction;
//或者
httpRequest.onreadystatechange = function(){
    // Process the server response here.
};
  1. 调用open方法设置基本的请求信息

httpRequest.open('GET', url, true); open()方法三个参数:第一个参数是请求方式 GET,POST,HEAD 等;第二个参数是请求地址url;第三个参数可选,用于设置请求是否是异步的,默认为true

  1. 调用send()方法 参数可以是任何你想发送给服务器的内容 httpRequest.send();

  2. 拿到返回值,处理数据更新页面

httpRequest.onreadystatechange=function (){
       if(httpRequest.readyState==4){
           if(httpRequest.status==200){
              //alert('成功了:'+httpRequest.responseText);
              fnSucc(httpRequest.responseText);
           }else{
              //alert('失败了');
              if(fnFaild){
                  fnFaild();
              }
           }
        }
    };

fetch 和 ajax的区别

  • 当接收到一个代表错误的 HTTP 状态码时,从 fetch() 返回的 Promise 不会被标记为 reject, 即使响应的 HTTP 状态码是 404 或 500。相反,它会将 Promise 状态标记为 resolve (但是会将 resolve 的返回值的 ok 属性设置为 false ),仅当网络故障时或请求被阻止时,才会标记为 reject。
  • fetch() 不会接受跨域 cookies;你也不能使用 fetch() 建立起跨域会话。其他网站的 Set-Cookie 头部字段将会被无视。
  • fetch 不会发送 cookies。除非你使用了credentials 的初始化选项。(自 2017 年 8 月 25 日以后,默认的 credentials 政策变更为 same-origin。Firefox 也在 61.0b13 版本中进行了修改)

什么是axios

Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。

特性

  • 从浏览器中创建 XMLHttpRequests
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF