zoukankan      html  css  js  c++  java
  • Fetch API

    一个隐藏最深的秘密就是AJAX的实现底层的XMLHttpRequest,这个方法本来并不是造出来干这事的。现在有很多优雅的API包装XHR,但是这远远不够。于是有了fetch API。我们来看看这个API的基本用法。最新的浏览器都已经支持这个方法了。

    XMLHttpRequest

    XHR对于我来说太过复杂,用起来大概是这样的:

    // 开始XHR这些
    if (window.XMLHttpRequest) { // Mozilla, Safari, ...
      request = new XMLHttpRequest();
    } else if (window.ActiveXObject) { // IE
      try {
        request = new ActiveXObject('Msxml2.XMLHTTP');
      } 
      catch (e) {
        try {
          request = new ActiveXObject('Microsoft.XMLHTTP');
        } 
        catch (e) {}
      }
    }
    
    // 发送请求.
    request.open('GET', 'https://davidwalsh.name/ajax-endpoint', true);
    request.send(null);
    

    当然我们的JavaScript框架可以让我们愿意去用XHR,但是你看到的只是一个简单的例子。

    基本的Fetch用法

    fetch方法可以在window作用域中找到。第一个参数是你要访问的URL:

    fetch('https://davidwalsh.name/some/url', {
    	method: 'get'
    }).then(function(response) {
    	
    }).catch(function(err) {
    	// Error :(
    });
    

    fetch会返回一个Promise作为结果:

    // 简单的返回结果处理
    fetch('https://davidwalsh.name/some/url').then(function(response) {
    	
    }).catch(function(err) {
    	// Error :(
    });
    
    // 更高级的链式处理
    fetch('https://davidwalsh.name/some/url').then(function(response) {
    	return //...
    }).then(function(returnedValue) {
    	// ...
    }).catch(function(err) {
    	// Error :(
    });

    通过 .then形式添加的回调函数,不论什么时候,都会被调用。
    通过多次调用.then,可以添加多个回调函数,它们会按照插入顺序并且独立运行。
    then 方法将返回一个 resolved 或 rejected 状态的 Promise 对象用于链式调用,且 Promise 对象的值就是这个返回值。
    const p = new Promise(function(resolve,reject){
      resolve(1);
    }).then(function(value){ // 第一个then // 1
      console.log(value);
      return value * 2;
    }).then(function(value){ // 第二个then // 2
      console.log(value);
    }).then(function(value){ // 第三个then // undefined
      console.log(value);
      return Promise.resolve('resolve');
    }).then(function(value){ // 第四个then // resolve
      console.log(value);
      return Promise.reject('reject');
    }).then(function(value){ // 第五个then //reject:reject
      console.log('resolve:' + value);
    }, function(err) {
      console.log('reject:' + err);
    });


    Request头

    请求能不能灵活使用就在于是否能灵活的设置请求的头。可以使用new Headers():

    // 创建一个空的Headers实例
    var headers = new Headers();
    
    // 添加内容
    headers.append('Content-Type', 'text/plain');
    headers.append('X-My-Custom-Header', 'CustomValue');
    
    // 检查Headers的值
    headers.has('Content-Type'); // true
    headers.get('Content-Type'); // "text/plain"
    headers.set('Content-Type', 'application/json');
    
    // 删除一个Header
    headers.delete('X-My-Custom-Header');
    
    // 添加初始值
    var headers = new Headers({
    	'Content-Type': 'text/plain',
    	'X-My-Custom-Header': 'CustomValue'
    });
    

    你可以使用appendhasgetsetdelete方法来设置请求的头。要使用Request头,需要创建一个Request实例:

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

    我们来看看ResponseRequest都可以做什么。

    Request

    一个Request实例代表了一个fetch的请求部分。给fetch 传入一个request你可以发出高级的、定制的请求:

    • method - GET, POST, PUT, DELETE, HEAD
    • url - URL of the request
    • headers - associated Headers object
    • referrer - referrer of the request
    • mode - cors, no-cors, same-origin
    • credentials - should cookies go with the request? omit, same-origin
    • redirect - follow, error, manual
    • integrity - subresource integrity value
    • cache - cache mode (default, reload, no-cache)

    一个简单的Request看起来是这样的:

    var request = new Request('https://davidwalsh.name/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方法,这个方法在Worker API里使用fetch 的时候很有用。fetch的简化调用方法:

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

    Respone

    使用fetch的then方法会获得一个Response实例。你也可以自己创建一个。

    • type - basic, cors
    • url
    • useFinalURL - Boolean for if url is the final URL
    • status - status code (ex: 200, 404, etc.)
    • ok - Boolean for successful response (status in the range 200-299)
    • statusText - status code (ex: OK)
    • headers - Headers object associated with the response.
    // 在service worker测试的时候
    // 使用new Response(BODY, OPTIONS)创建一个response
    var response = new Response('.....', {
    	ok: false,
    	status: 404,
    	url: '/'
    });
    
    // The fetch的 `then`会获得一个response实例
    fetch('https://davidwalsh.name/')
    	.then(function(responseObj) {
    		console.log('status: ', responseObj.status);
    	});
    

    Response实例也提供了如下的方法:

    • clone() - Creates a clone of a Response object.
    • error() - Returns a new Response object associated with a network error.
    • redirect() - Creates a new response with a different URL.
    • arrayBuffer() - Returns a promise that resolves with an ArrayBuffer.
    • blob() - Returns a promise that resolves with a Blob.
    • formData() - Returns a promise that resolves with a FormData object.
    • json() - Returns a promise that resolves with a JSON object.
    • text() - Returns a promise that resolves with a USVString (text).

    处理JSON

    假设你有一个请求会返回JSON。

    fetch('https://davidwalsh.name/demo/arsenal.json').then(function(response) { 
    	// Convert to JSON
    	return response.json();
    }).then(function(j) {
    	// Yay, `j` is a JavaScript object
    	console.log(j); 
    });
    
    

    当然也可以用JSON.parse(jsonString),但是json方法更加简单易用。

    处理基本的Text/HTML返回

    不是所有的接口都返回JSON格式的数据,所以还要处理一些Text/HTML类型的返回结果。

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

    处理Blob返回

    如果你想要通过fetch加载一个blob的话,会有一点不同:

    fetch('https://davidwalsh.name/flowers.jpg')
    	.then(function(response) {
    	  return response.blob();
    	})
    	.then(function(imageBlob) {
    	  document.querySelector('img').src = URL.createObjectURL(imageBlob); //把二进制流转为一个临时url(这个url的生命周期同网页的生命周期是一样的)
    	});
    

    POST Form数据

    另一个经常会遇到的情况是使用AJAX提交表单数据。

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

    最后

    fetchAPI很好用,但是现在还不允许取消一个请求。无论如何,有了fetch之后,我们可以简单的发出AJAX请求了。更多关于fetch 的内容可以参考Github下他们的repo

    欢迎加群互相学习,共同进步。QQ群:iOS: 58099570 | Android: 572064792 | Nodejs:329118122 做人要厚道,转载请注明出处!
    分类: Javascript
    标签: javascriptfetchapi
    好文要顶 关注我 收藏该文  
    0
    0
    « 上一篇: React Native填坑之旅--Stateless组件
    » 下一篇: 如何在NodeJS项目中优雅的使用ES6

    posted on 2017-01-15 09:30  Mr 布鲁斯  阅读(2701)  评论(0)  编辑  收藏

  • 相关阅读:
    HDU 5583 Kingdom of Black and White 水题
    HDU 5578 Friendship of Frog 水题
    Codeforces Round #190 (Div. 2) E. Ciel the Commander 点分治
    hdu 5594 ZYB's Prime 最大流
    hdu 5593 ZYB's Tree 树形dp
    hdu 5592 ZYB's Game 树状数组
    hdu 5591 ZYB's Game 博弈论
    HDU 5590 ZYB's Biology 水题
    cdoj 1256 昊昊爱运动 预处理/前缀和
    cdoj 1255 斓少摘苹果 贪心
  • 原文地址:https://www.cnblogs.com/qqhfeng/p/13975968.html
Copyright © 2011-2022 走看看