Fetch Vue-Resource axios

佘俊茂
2023-12-01

axios和fetch的区别在于axios的response是一个综合各种方法的对象,并不是请求数据,需要经过处理后才能使用;fetch现在上没有取消请求的机制,axios存在取消请求的机制

1.Fetch

fetch安装

为了解决 fetch 的兼容性,我们使用 Fetch Polyfill 的版本 whatwg-fetch。

npm install --save whatwg-fetch
import 'whatwg-fetch'

webpack 项目增加(加不加都可以)

entry: ['whatwg-fetch', ...]

也可以用另一个 fetch 版本

npm install --save isomorphic-fetch

fetch 的基本使用

fetch 是全局量 window 的一个方法, 第一个参数是URL:

// url (必须), options (可选)
fetch('/some/url', {
    method: 'get'
}).then(function(response) {
 
}).catch(function(err) {
    // 出错了;等价于 then 的第二个参数,但这样更好用更直观 :(
});

和 Battery API 类似, fetch API 也使用了 JavaScript Promises 来处理结果/回调:

// 链式处理,将异步变为类似单线程的写法: 高级用法.
fetch('/some/url').then(function(response) {
    return //... 执行成功, 第1步...
}).then(function(returnedValue) {
    // ... 执行成功, 第2步...
}).catch(function(err) {
    // 中途任何地方出错...在此处理 :( 
});

请求头(Request Headers)

自定义请求头信息极大地增强了请求的灵活性。我们可以通过 new Headers() 来创建请求头:

// 创建对象时设置初始化信息
var headers = new Headers({
	'Content-Type': 'text/plain',    
	'X-My-Custom-Header': 'CustomValue'
});
 
// 添加(append)请求头信息
headers.append('Content-Type', 'text/plain');
headers.append('X-My-Custom-Header', 'CustomValue');
 
// 判断(has), 获取(get), 以及修改(set)请求头的值
headers.has('Content-Type'); // true
headers.get('Content-Type'); // "text/plain"
headers.set('Content-Type', 'application/json');
 
// 删除某条请求头信息(a header)
headers.delete('X-My-Custom-Header');

headers 可以使用的方法包括: append, has, get, set, 以及 delete 。需要创建一个 Request 对象来包装请求头:

var request = new Request('/some-url', {
    headers: new Headers({
        'Content-Type': 'text/plain'
    })
});
 
fetch(request).then(function(response) { /* handle response */ });

下面介绍 Request 和 Response 的使用方法!

Request 简介

Request 对象表示一次 fetch 调用的请求信息。传入 Request 参数来调用 fetch, 可以执行很多自定义请求的高级用法:

  • method - 支持 GET, POST, PUT, DELETE, HEAD

  • url - 请求的 URL

  • headers - 对应的 Headers 对象

  • body - 请求参数(JSON.stringify 过的字符串或 ‘name=jim&age=22’ 格式)

  • referrer - 请求的引用者(例如:client)

  • mode - 是否允许跨域请求,以及哪些响应的属性是可读的。可选值:
    cors:(默认),允许跨域请求,将遵守 CORS 协议。
    no-cors:该模式允许来自 CDN 的脚本、其他域的图片和其他一些跨域资源。前提条件是请求的 method 只能是 HEAD、GET 或 POST。此外,如果 ServiceWorkers 拦截了这些请求,它不能随意添加或者修改除这些之外 Header 属性。第三,js 不能访问 Response 对象中的任何属性,这确保了跨域时 ServiceWorkers 的安全和隐私信息泄露问题。
    same-origin:如果是一个跨域请求,将返回一个 error。
    navigate:支持导航的模式,仅用于 HTML 导航。

  • credentials - 设置 cookies 是否随请求一起发送。可选值:
    omit:(默认),不发送 Cookie。
    same-origin:同域下自动发送 Cookie。
    include:始终发送 Cookie,即使是跨域。

  • redirect - 定义重定向处理方式。可选值:follow(默认), error, manual。

  • integrity - 子资源完整性值。

  • cache - 设置缓存模式。可选值:
    default:浏览器在其 HTTP 缓存中查找匹配的请求。

     a. 如果匹配并且是新鲜的,它将从缓存中返回。
     b. 如果存在匹配但已失效,则浏览器将向远程服务器发出有条件的请求。如果服务器指出资源没有改变,它将从缓存中返回。否则资源将从服务器下载并且缓存将被更新。
     c. 如果没有匹配,浏览器将发出正常的请求,并且下载的资源更新缓存。
    

    no-store:浏览器从远程服务器获取资源,而不先查看缓存,并且不会使用下载的资源更新缓存。
    reload:浏览器从远程服务器获取资源,而不先查看缓存,但随后将使用下载的资源更新缓存。
    no-cache:浏览器在其 HTTP 缓存中查找匹配的请求。

     a. 如果匹配,新鲜或陈旧,浏览器将向远程服务器发出有条件的请求。如果服务器指出资源没有改变,它将从缓存中返回。否则资源将从服务器下载并且缓存将被更新
     b. 如果没有匹配,浏览器将发出正常的请求,并用下载的资源更新缓存。
    

    force-cache:浏览器在其 HTTP 缓存中查找匹配的请求。

     a. 如果有匹配,新鲜或陈旧,它将从缓存中返回。
     b. 如果没有匹配,浏览器将发出正常的请求,并用下载的资源更新缓存。
    

    only-if-cached:浏览器在其 HTTP 缓存中查找匹配的请求。只能用在 mode 为 same-origin 的情况下

     a. 如果匹配,新鲜或陈旧,将从缓存中返回。
     b. 如果没有匹配,浏览器将返回一个错误。
    

Request 的示例如下:

var request = new Request('/users.json', {
    method: 'POST', 
    mode: 'cors', 
    redirect: 'follow',
    headers: new Headers({
        'Content-Type': 'text/plain'
    })
});
 
// 使用!
fetch(request).then(function() { /* handle response */ });

只有第一个参数 URL 是必需的。在 Request 对象创建完成之后, 所有的属性都变为只读属性. 请注意, Request 有一个很重要的 clone 方法, 特别是在 Service Worker API 中使用时 —— 一个 Request 就代表一串流(stream), 如果想要传递给另一个 fetch方法,则需要进行克隆。

fetch 的方法签名(signature,可理解为配置参数), 和 Request 很像, 示例如下:

fetch('/users.json', {
    method: 'POST', 
    mode: 'cors', 
    redirect: 'follow',
    headers: new Headers({
        'Content-Type': 'text/plain'
    })
}).then(function() { /* handle response */ });

因为 Request 和 fetch 的签名一致, 所以在 Service Workers 中, 你可能会更喜欢使用 Request 对象。关于 ServiceWorker 的相关博客请等待后续更新!

提交表单数据(Posting Form Data)

另一种常用的 AJAX 调用是提交表单数据 —— 示例代码如下:

fetch('/submit', {
    method: 'post',
    body: new FormData(document.getElementById('comment-form'))
});

提交 JSON 的示例如下:

fetch('/submit-json', {
    method: 'post',
    body: JSON.stringify({
        email: 'huang@163.com'
        name: 'jim'
    })
});

Response 简介

Response 代表响应, fetch 的 then 方法接收一个 Response 实例, 当然你也可以手动创建 Response 对象 —— 比如在 service workers 中可能会用到. Response 可以配置的参数包括:

  • type - 类型,支持: basic, cors

  • url - 响应的 URL

  • useFinalURL - Boolean 值, 说明这是否是响应的最终 URL

  • status - 状态码 (例如: 200, 404, 等等)

  • ok - Boolean值,代表响应是否成功(status 值在 200-299 之间)

  • statusText - 与状态码相对应的状态值(例如: OK为200)

  • headers - 与响应相关联的 Headers 对象.

  • redirected - 指示响应是否是重定向的结果。也就是说,它的 URL 列表有多条目录。

     // 在 service worker 测试中手动创建 response
     // new Response(BODY, OPTIONS)
     var response = new Response('.....', {
     	ok: false,
     	status: 404,
     	url: '/'
     });
    
     // fetch 的 `then` 会传入一个 Response 对象
     fetch('/')
     	.then(function(responseObj) {
         	console.log('status: ', responseObj.status);
     	});
    

Fetch 第一个 then 接受到的数据格式如下:

第二个 then 接收到的参数才是后台真正传过来的数据。

Response 提供的方法如下:

  • clone() - 创建一个 Response 对象的克隆.
  • error() - 返回一个与网络错误相关的新 Response 对象.
  • redirect() - 重定向,使用新的 URL 创建新的 response 对象…
  • arrayBuffer() - 返回一个 resolve 是 ArrayBuffer 的 promise 对象。
  • blob() - 返回一个 resolve 是 Blob 的 promise 对象。
  • formData() - 返回一个 resolve 是 FormData 的 promise 对象。
  • json() - 返回一个 resolve 是 JSON 的 promise 对象。
  • text() - 返回一个 resolve 是文本的 promise 对象。

处理 JSON响应

假设需要请求 JSON —— 回调结果对象 response 中有一个json()方法,用来将原始数据转换成 json 对象:

fetch('https://davidwalsh.name/demo/arsenal.json').then(function(response) { 
    // 转换为 JSON
    return response.json();
}).then(function(j) {
    // 现在, `j` 是一个 json 对象
    console.log(j); 
});

当然这很简单 , 只是封装了 JSON.parse(jsonString) 而已, 但 json 方法还是很方便的。
处理基本的Text / HTML响应

JSON 并不总是理想的请求/响应数据格式, 那么我们看看如何处理 HTML或文本结果:

fetch('/next/page')
  .then(function(response) {
    return response.text();
  }).then(function(text) { 
    // <!DOCTYPE ....
    console.log(text); 
  });

如上面的代码所示, 可以在 Promise 链式的 then 方法中, 先返回 text() 结果 ,再获取 text 。

处理Blob结果

如果你想通过 fetch 加载图像或者其他二进制数据, 则会略有不同:

fetch('flowers.jpg')
    .then(function(response) {
      return response.blob();
    })
    .then(function(imageBlob) {
      document.querySelector('img').src = URL.createObjectURL(imageBlob);
    });

响应 Body mixin 的 blob() 方法处理响应流(Response stream), 并且将其读完。

未完的故事(Unwritten Story)

fetch 是个很实用的API , 当前还不允许取消请求, 这使得很多程序员暂时不会考虑它。

新的 fetch API 比起 XHR 更简单也更智能。毕竟,它就是专为AJAX而设计的, 具有后发优势. 而我已经迫不及待地使用了, 即使现在兼容性还不是那么好!

2.axios

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征

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

引入方式

$ npm install axios
$ cnpm install axios //taobao源
$ bower install axios
或者使用cdn:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>

基本使用
GET请求

// 向具有指定ID的用户发出请求
axios.get('/user?ID=12345')
.then(function (response) {
	console.log(response);
})
.catch(function (error) {
	console.log(error);
});

// 也可以通过 params 对象传递参数
axios.get('/user', {
	params: {
		ID: 12345
	}
})
.then(function (response) {
	console.log(response);
})
.catch(function (error) {
	console.log(error);
});

POST请求

axios.post('/user', {
	firstName: 'Fred',
	lastName: 'Flintstone'
})
.then(function (response) {
	console.log(response);
})
.catch(function (error) {
	console.log(error);
});

执行多个并发请求

function getUserAccount() {
	return axios.get('/user/12345');
}

function getUserPermissions() {
	return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
.then(axios.spread(function (acct, perms) {
	//两个请求现已完成
}));

请求方法别名

为了方便起见,已经为所有支持的请求方法提供了别名。

axios.request(config)
axios.get(url [,config])
axios.delete(url [,config])
axios.head(url [,config])
axios.post(url [,data [,config]])
axios.put(url [,data [,config]])
axios.patch(url [,data [,config]])

拦截器
你可以截取请求或响应在被 then 或者 catch 处理之前

//添加请求拦截器
axios.interceptors.request.use(function(config){
	//在发送请求之前做某事
	return config;
},function(error){
	//请求错误时做些事
	return Promise.reject(error);
});

//添加响应拦截器
axios.interceptors.response.use(function(response){
	//对响应数据做些事
	return response;
},function(error){
	//请求错误时做些事
	return Promise.reject(error);
});

删除拦截器

var myInterceptor = axios.interceptors.request.use(function () {/*...*/});
axios.interceptors.request.eject(myInterceptor);

你可以将拦截器添加到axios的自定义实例

var instance = axios.create();
instance.interceptors.request.use(function () {/*...*/});

处理错误

axios.get('/ user / 12345')
.catch(function(error){
	if(error.response){
		//请求已发出,但服务器使用状态代码进行响应
		//落在2xx的范围之外
		console.log(error.response.data);
		console.log(error.response.status);
		console.log(error.response.headers);
	} else {
		//在设置触发错误的请求时发生了错误
		console.log('Error',error.message);
	}}
	console.log(error.config);
});

您可以使用validateStatus配置选项定义自定义HTTP状态码错误范围

axios.get('/ user / 12345',{
	validateStatus:function(status){
		return status < 500; //仅当状态代码大于或等于500时拒绝
	}}
})

消除
您可以使用取消令牌取消请求
可以使用 CancelToken.source 工厂方法创建 cancel token,像这样:

var CancelToken = axios.CancelToken;
var source = CancelToken.source();

axios.get('/user/12345', {
	cancelToken: source.token
}).catch(function(thrown) {
	if (axios.isCancel(thrown)) {
		console.log('Request canceled', thrown.message);
	} else {
		// 处理错误
	}
});

// 取消请求(message 参数是可选的)
source.cancel('Operation canceled by the user.');

还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token:

var CancelToken = axios.CancelToken;
var cancel;

axios.get('/user/12345', {
	cancelToken: new CancelToken(function executor(c) {
		// executor 函数接收一个 cancel 函数作为参数
		cancel = c;
	})
});

// 取消请求
cancel();

3.Vue-Resource

Vue.js是数据驱动的,这使得我们并不需要直接操作DOM,如果我们不需要使用jQuery的DOM选择器,就没有必要引入jQuery。vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应。也就是说,$.ajax能做的事情,vue-resource插件一样也能做到,而且vue-resource的API更为简洁。另外,vue-resource还提供了非常有用的inteceptor功能,使用inteceptor可以在请求前和请求后附加一些行为,比如使用inteceptor在ajax请求时显示loading界面。
vue2.0之后,就不再对vue-resource更新,而是推荐使用axios。

安装引入

$ cnpm install vue-resource

基础使用

引入vue-resource后,可以基于全局的Vue对象使用http,也可以基于某个Vue实例使用http

// 基于全局Vue对象使用http
Vue.http.get('/someUrl', [options]).then(successCallback, errorCallback);
Vue.http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);

// 在一个Vue实例内使用$http
this.$http.get('/someUrl', [options]).then(successCallback, errorCallback);
this.$http.post('/someUrl', [body], [options]).then(successCallback, errorCallback);

在发送请求后,使用then方法来处理响应结果,then方法有两个参数,第一个参数是响应成功时的回调函数,第二个参数是响应失败时的回调函数。
then方法的回调函数也有两种写法,第一种是传统的函数写法,第二种是更为简洁的ES 6的Lambda写法:

// 传统写法
this.$http.get('/someUrl', [options]).then(function(response){
	// 响应成功回调
}, function(response){
	// 响应错误回调
});
// Lambda写法
this.$http.get('/someUrl', [options]).then((response) => {
	// 响应成功回调
}, (response) => {
	// 响应错误回调
});

支持的HTTP方法

get(url, [options])
head(url, [options])
delete(url, [options])
jsonp(url, [options])
post(url, [body], [options])
put(url, [body], [options])
patch(url, [body], [options])

options对象

参数类型描述
url string 请求的URL
method string 请求的HTTP方法,例如:'GET', 'POST'或其他HTTP方法
body Object, FormData string request body
params Object 请求的URL参数对象
headers Object request header
timeout number 单位为毫秒的请求超时时间 (0 表示无超时时间)
before function(request) 请求发送前的处理函数,类似于jQuery的beforeSend函数
progress function(event) ProgressEvent回调处理函数
credentials boolean 表示跨域请求时是否需要使用凭证
emulateHTTP boolean 发送PUT, PATCH, DELETE请求时以HTTP POST的方式发送,并设置请求头的X-HTTP-Method-Override
emulateJSON boolean 将request body以application/x-www-form-urlencoded content type发送

response对象

方法类型描述
text() string 以string形式返回response body
json() Object 以JSON对象形式返回response body
blob() Blob 以二进制形式返回response body
属性 类型 描述
ok boolean 响应的HTTP状态码在200~299之间时,该属性为true
status number 响应的HTTP状态码
statusText string 响应的状态文本
headers Object 响应头
 类似资料:

相关阅读

相关文章

相关问答