ChuChencheng / note

菜鸡零碎知识笔记
Creative Commons Zero v1.0 Universal
3 stars 0 forks source link

JavaScript 网络请求的几种方式 #41

Open ChuChencheng opened 4 years ago

ChuChencheng commented 4 years ago

XMLHttpRequest

XMLHttpRequest(XHR)对象可以与服务器交互,可以从 URL 获取数据,而无需刷新整个页面。

基本用法

function sendAjax() {
  //构造表单数据
  var formData = new FormData();
  formData.append('username', 'johndoe');
  formData.append('id', 123456);
  //创建xhr对象 
  var xhr = new XMLHttpRequest();
  //设置xhr请求的超时时间
  xhr.timeout = 3000;
  //设置响应返回的数据格式
  xhr.responseType = "text";
  //创建一个 post 请求,采用异步
  xhr.open('POST', '/server', true);
  //注册相关事件回调处理函数
  xhr.onload = function(e) { 
    if(this.status == 200||this.status == 304){
        alert(this.responseText);
    }
  };
  xhr.ontimeout = function(e) { ... };
  xhr.onerror = function(e) { ... };
  xhr.upload.onprogress = function(e) { ... };

  //发送数据
  xhr.send(formData);
}

readyState

XMLHttpRequest.UNSENT === 0 // 代理被创建,但尚未调用 open() 方法。
XMLHttpRequest.OPENED=== 1 // open() 方法已经被调用。
XMLHttpRequest.HEADERS_RECEIVED=== 2 // send() 方法已经被调用,并且头部和状态已经可获得。
XMLHttpRequest.LOADING === 3 // 下载中; responseText 属性已经包含部分数据。
XMLHttpRequest.DONE === 4 // 下载操作已完成。

取消请求

xhr.abort()

Fetch

Fetch 提供了对 RequestResponse 对象的通用定义,使之可以被应用到更多场景中,例如 Service Worker、Cache API 等。

基本用法

// 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
}

fetch 返回一个 Promise ,并 resolve 一个 Response 对象,只有在网络故障或主动中断请求时会 reject 。

fetch 与 jQuery.ajax() 的不同

取消请求

通过 AbortSignal API 来中断 fetch 发起的请求。

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

Axios

axios 是一个开源的 http 库,基于 Promise ,可用于浏览器与 Node.js 端。

基本用法

// Send a POST request
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
}).then((response) => {});

取消请求

使用 CancelToken.source

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 {
    // handle error
  }
});

axios.post('/user/12345', {
  name: 'new name'
}, {
  cancelToken: source.token
})

// cancel the request (the message parameter is optional)
source.cancel('Operation canceled by the user.');

使用 CancelToken 构造函数:

const CancelToken = axios.CancelToken;
let cancel;

axios.get('/user/12345', {
  cancelToken: new CancelToken(function executor(c) {
    // An executor function receives a cancel function as a parameter
    cancel = c;
  })
});

// cancel the request
cancel();

jQuery.ajax()

基本用法

$.ajax({
  url: '/url',
  type: 'POST',
  data: {
    form: 'data',
  },
  dataType: 'json',
}).done((response) => {
}).fail(() => {
}).always(() => {})

返回一个 jqXHR 对象

取消请求

const jqXHR = $.ajax({
  // settintgs...
})

jqXHR.abort()

参考