如何使用 fetch ,加请求头, ajax 和 fetch 和 axios 的区别_weixin_34403693的博客-程序员宅基地

技术标签: ViewUI  json  javascript  

----欢迎查看我的博客----

什么是fetch

  我们之前,过度过来都在用ajax,那么什么是 Fetch ,Fetch 是新的游览器对象, 等同于 XMLHttpRequest对象 。它提供了许多与 XMLHttpRequest 相同的功能,但被设计成更具可扩展性和高效性。

ajax

  废话不多说我们来看一下传统的ajax。

var xhr;
if (window.XMLHttpRequest) {
    xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
    try {
        xhr = new ActiveXObject('Msxml2.XMLHTTP');
    } catch (e) {
     try {
        xhr = new ActiveXObject('Microsoft.XMLHTTP');
    } catch (e) {}
    }
}
if (xhr) {
    xhr.onreadystatechange = () =>{
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                console.log(xhr.responseText); //返回值传callback
            } else {
			//failcallback
			console.log('There was a problem with the request.');
		    }
        } else {
            console.log('still not ready...');
        }
    };
    xhr.open('POST', 'https://www.baidu.com', true);
    // 设置 Content-Type 为 application/x-www-form-urlencoded
    // 以表单的形式传递数据
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.send('username=admin&password=root');
    
}

复制代码

  好我们来做层封装,让他变成我们 jQuery 的 ajax post 如这种形式:

$.ajax({
    method: 'POST', //请求方式
    url: '/api', //url
    data: { username: 'admin', password: 'root' }, //值
	success:function(data){ //成功回掉
		console.log(data)
	},
	error:function(err){
		console.log(err)
	}
})
复制代码

好的封装开始:

const $ = {};
$.ajax = (obj)=>{
	var xhr;
	if (window.XMLHttpRequest) {
	   xhr = new XMLHttpRequest();
	} else if (window.ActiveXObject) { // IE
	   try {
		 xhr = new ActiveXObject('Msxml2.XMLHTTP');
	   } catch (e) {
		 try {
		   xhr = new ActiveXObject('Microsoft.XMLHTTP');
		 } catch (e) {}
	   }
	}
	if (xhr) {
	   xhr.onreadystatechange = () =>{
		   if (xhr.readyState === 4) {
			  if (xhr.status === 200) {
				 obj.success(xhr.responseText); //返回值传callback
			  } else {
					//failcallback
				 obj.error('There was a problem with the request.');
			  }
		   } else {
			  console.log('still not ready...');
		   }
		};
	   xhr.open(obj.method, obj.url, true);
	   // 设置 Content-Type 为 application/x-www-form-urlencoded
	   // 以表单的形式传递数据
	   xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	   xhr.send(util(obj.data));//处理body数据
	}
	
	//处理数据
	const util = (obj)=>{
		var str = ''
		for (key in obj){
			str += key +'='+obj[key]+'&'

		}
		return str.substring(0,str.length-1)
	}
	
}
复制代码

  ok,咱们已经封装完毕,可以使用了,可是你会发现,这种书写方式很混乱,body,hearder乱七八糟,还有回掉地狱的问题。好的fetch出来了。

fetch的出现

  我们说了,一种东西的诞生有它的道理,他首先解决了回掉地狱的问题因为返回一个 promise 对象 ,对 promise 对象不是很熟悉的同学可以看这篇文章: 你就需要这篇文章,带你搞懂实战的 Promise 对象。同样既然是 promise 对象我们就可以使用 es7 的 async / await 戳这里。好了废话不多说我们看看最基础的 fetch 怎么写吧 。

fetch(url, options).then(function(response) {
  // handle HTTP response
}, function(error) {
  // handle network error
})
复制代码

  就是这么方便,就是这么简单。 fetch 会先发起一个 option 的请求,确定是否连接成功,然后再发送正式的请求 ,就好比 xhr.readyState === 4 这个一个道理。那有同学就问了,我的逻辑比较复杂 。我的 fetch 要加请求头,参数我要传参传 formData 不是 json。 我们来看fetch发送formdata:

fetch(url,{
    method:"post",
    headers:{
        "Content-type":"application:/x-www-form-urlencoded:charset=UTF-8"
    },
    body:"name=admin&password=123456"
}).then(function(response){
	if(response.ok){
		response.json().then(json => {
              console.log(json.result)
        })
	}
}).catch(function(err){
    console.log("Fetch错误:"+err);
});
复制代码

  发送json格式也非常简单。

fetch(url,{
    method:"post",
    headers:{
       'Content-Type':'application/json; charset=UTF-8'
    },
    body:JSON.stringify({
    name:'admin',password:123456})
}).then(function(response){
	if(response.ok){
		response.json().then(json => {
              console.log(json.result)
        })
	}
}).catch(function(err){
    console.log("Fetch错误:"+err);
});
复制代码

中止 取消 fetch

浏览器已经开始为 AbortControllerAbortSignal 接口(也就是Abort API)添加实验性支持,允许像 Fetch 和 XHR 这样的操作在还未完成时被中止 。请参阅接口页面了解更多详情。但是目前对游览器的支持并不很好,所以我们其实可以换一种思路, 取消 fetch 我们可以从另外一个面入手 ---- 可以取消 promise 。原生的当然不行了,所以我们这里用到了 bluebird

例如多个 fetch:


//传统 promise
var promises = [];
for (var i = 0; i < fileNames.length; ++i) {
    promises.push(fs.readFileAsync(fileNames[i]));
}
Promise.all(promises).then(function() {
    console.log("done");
});

// Using Promise.map:
import Promise from 'bluebird'
Promise.map(fileNames, function(fileName) {
    // Promise.map awaits for returned promises as well.
    return fs.readFileAsync(fileName);
}).then(function() {
    console.log("done");
});

复制代码

终止取消多个 fetch:

import Promise from 'bluebird'
Promise.map(fileNames, function(fileName) {
    // Promise.map awaits for returned promises as well.
    return fs.readFileAsync(fileName).then(()=>{
                //如果flag = true 就中断。
                if (flag){
                  throw new Error('中断')
                }
            });;
}).then(function() {
    console.log("done");
}).catch(function (err) {
    console.log('Error', err.message)
});
复制代码

如果取消单个 promise 可以用 .cancel 方法,具体看 bluebird 文档。

Axios 的出现

  从文档中我们可以看出为什么这个会火 ,axios 他的功能非常强大,包括 取消请求 ,进度处理等等。但是我们看的是本质还是 ajax ,在基础上进行了封装和功能的添加

XMLHttpRequests 支持 Promise

//一个post请求

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

复制代码

结语

  其实我们看出来, ajax 和 Axios 在客户端都是调用 XMLHttpRequests 对象 ,而我们的 fetch 是一个新的游览器对象 。只不过 ajax 和 Axios 区别就是在 封装了简便的方法,并且提供了一个 promise 对象。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34403693/article/details/88023054

智能推荐

Eplan p8 v2.7 卡顿问题_eplan p8 2.7卡顿怎么解决-程序员宅基地

安装Eplan P8 v2.7后,使用过程中会感觉一卡一卡的,这时你到你下载的软件破解文件中,找到version.dll,将其复制到Eplan执行文件所在目录即可。在Eplan执行文件右键->属性->快捷方式页->打开文件所在位置,即可直接定位到Eplan执行文件目录。..._eplan p8 2.7卡顿怎么解决

写一函数,将两个字符串中的元音字母复制到另一个字符串,然后输出。-程序员宅基地

题目描述写一函数,将两个字符串中的元音字母复制到另一个字符串,然后输出。输入一行字符串输出顺序输出其中的元音字母(aeiuo)样例输入abcde样例输出ae#include#includeint main(){ int i,j; char a[100],b[100];

ContentProvider完整案例,android混合开发教程-程序员宅基地

*/public class TeacherContentProvider extends ContentProvider {private DBOpenHelper dbOpenHelper = null;// UriMatcher类用来匹配Uri,使用match()方法匹配路径时返回匹配码/**是一个回调函数,在ContentProvider创建的时候,就会运行,第二个参数为指定数据库名称,如果不指定,就会找不到数据库;如果数据库存在的情况下是不会再创建一个数据库的。(当然首次调用

面试题之测试开发-程序员宅基地

1 面试基础1).测试基础设计用例方法,bug属性,好的测试流程,紧急需求处理,问题排查,质量提升,get/post区别,MQ优缺点2) 测试工具postman,bug、用例管理工具等2 自动化测试1)测试框架包括框架架构,运行原理等2)自动化流程自动化脚本补充、怎么执行自动化脚本、自动化覆盖率统计、自动化脚本维护,过程中遇到的问题,怎么处理的(想一个典型的问题,和自己解决的方法...

安卓 android:windowsoftinputmode,android:windowSoftInputMode =“adjustPan”不起作...-程序员宅基地

首先确保您在xml布局中提供了ScrollView.android:layout_width="match_parent"android:layout_height="match_parent" >......然后在你的活动中确保你正在做这样的事情(这段代码只是为了演示在哪里使用getWindow().setSoftInputMode(WindowManager.LayoutParams.S..._android:windowsoftinputmode="statealwayshidden|adjustpan" 不起作用,app无法弹

2020-12-21_[error] 2020-12-22t05:38:21.324263z nonode@nohost -程序员宅基地

#include <stdio.h>int main(){ printf("输入一行字符:\n"); char ch; int i,count=0,word=0; while((ch=getchar())!='\n') if(ch==' ') word=0; else if(word==0) { word=1; count++; _[error] 2020-12-22t05:38:21.324263z nonode@nohost emulator -------- error in

随便推点

Docker 最新版本安装教程_docker 安装新版本-程序员宅基地

1:安装docker2.配置开机启动3:配置docker源_docker 安装新版本

JAVA程序员平常加班严重, 如何有效率的提升自己?_java工程师加班严重吗-程序员宅基地

每天加班到10点多,程序员如何安排时间提升自己,比如学习英语,或参加MBA课程,广泛社交等? 回顾我的提升之路,我觉得有几点可以跟大家分享的:第一是「兴趣」。这也是我认为最重要的一点,一件事情做 10 年甚至做一辈子,如果没有兴趣的话,我觉得是很痛苦的。兴趣是本能的驱动力,有了兴趣..._java工程师加班严重吗

SFTP文件上传与下载-程序员宅基地

SFTP是对ftp进行加密的一种文件协议.首先是先引入:jsch-0.1.42-sources.jar与jsch-0.1.42.jar包SFTP文件上传与下载。import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.util.P..._jsch-0.1.24.jar

ABAP TC 响应双击事件-程序员宅基地

1.在status注册事件 和普通的按钮一样对应 热键F2 这里假设:事件码 =SELE2.WHEN 'SELE'. DATA:l_cursor TYPE i, ind TYPE i. "获取选中的行的下标 然后就可以进行逻辑处理了 ZTC是TC的名字 GETCURSOR LINE l_cursor. ind =ZTC-

Improved Differentiable Architecture Search for Language Modeling and Named Entity Recognition 论文笔记-程序员宅基地

Improved Differentiable Architecture Search for Language Modeling and Named Entity RecognitionDARTS : Differentiable Architecture SearchAbstractstrong baselines是什么?IntroductionDARTS将搜索空间松弛到连续的领域,...

mysql 开启 远程连接_mysql开启远程连接_梦塔谈架构的博客-程序员宅基地

安装好 mysql 后,一般会使用客户端连接(必须Navcat)。本文描述了怎么设置远程连接。先看下 用户表的信息注意:这里的 root 账户的 host 的值是 localhost开始修改,执行:修改后:注意:这里的 root 账户的 host 的值变成了 %% 这个百分号表示的意思是任意机器都可以连接,也可以缓存你机器的固定ip。3.3 为防火墙添加 3306 端口高高兴兴的打开连接,发现:does not support authentication protocol不得已,继续开始设置s_mysql开启远程连接