一. Promise相关

1.说明

  主要解决异步深层嵌套的问题,promise 提供了简洁的API 使得异步操作更加容易 。

2.入门使用

  我们使用new来构建一个Promise Promise的构造函数接收一个参数,是函数,并且传入两个参数:resolve,reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。

    var p = new Promise(function(resolve, reject) {
// 这里用于实现异步任务
setTimeout(function() {
var flag = false;
if (flag) {
// 正常情况
resolve('hello');
} else {
// 异常情况
reject('出错了');
         }
}, 100);
});
p.then(function(data) {
console.log(data)
}, function(info) {
console.log(info)
});

补充:回调地狱问题解决? 

3. 基本Api

  then-catch-finally, 其中then-catch等价于 then(fun1,fun2),fun2相当于catch。

代码:

      function foo() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
// resolve(123);
reject('error');
}, 100);
})
}
// foo()
// .then(function(data){
// console.log(data)
// })
// .catch(function(data){
// console.log(data)
// })
// .finally(function(){
// console.log('finished')
// }); // --------------------------
// 两种写法是等效的
foo()
.then(function(data) {
console.log(data)
}, function(data) {
console.log(data)
})
.finally(function() {
console.log('finished')
});

4.对象方法

(1). all:方法接受一个数组作参数,数组中的对象(p1、p2、p3)均为promise实例(如果不是一个promise,该项会被用 Promise.resolve 转换为一个promise)。它的状态由这三个promise实例决定。

(2). race:Promise.race 方法同样接受一个数组作参数。当p1, p2, p3中有一个实例的状态发生改变(变为 fulfilled或 rejected ),p的状态就跟着改变。并把第一个改变状态的promise的返回值传给p的回调函数。

代码分享:

二. Fetch用法

补充:

参考 API文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API/Using_Fetch

其它参考:https://www.cnblogs.com/wonyun/p/fetch_polyfill_timeout_jsonp_cookie_progress.html

用到的服务端接口方法:

     [Route("api/[controller]/[action]")]
[ApiController]
public class FirstController : ControllerBase
{ /******************************************下面是测试Get请求的相关方法***************************************************/ #region 下面是测试Get请求的相关方法
[HttpGet]
public string GetInfor1(string userName, string pwd)
{
return $"{userName}+{pwd}";
} [HttpGet]
public string GetInfor2([FromQuery]UserInfor model)
{
return $"{model.userName}+{model.pwd}";
}
[HttpGet]
//加上[FromQuery]也报错
public string GetInfor3([FromQuery]dynamic model)
{
return $"{model.userName}+{model.pwd}";
} #endregion }
[Route("api/[controller]/[action]")]
[ApiController]
public class ThirdController : Controller
{
[HttpGet]
public IActionResult GetInfor4(string userName, string pwd)
{
return Json(new
{
userName,
pwd
});
}
}

1.简介

  Fetch API是新的ajax解决方案 Fetch会返回Promise, fetch不是ajax的进一步封装,而是原生js,不需要引入任何库,没有使用XMLHttpRequest对象。

2.基本用法

  (1).通用格式 fetch().then().then().catch() ,第一个then处理返回类型,在第二个then里才拿到返回值,里面的function可以简化写法。

  (2).默认是get请求。

代码分享:

                        //默认是Get请求的
fetch("https://localhost:44387/api/First/GetInfor1?userName=ypf&pwd=123456").then(function(data) {
return data.text();
}).then(function(data) {
console.log(data);
}); //简洁写法:
fetch("https://localhost:44387/api/First/GetInfor1?userName=ypf&pwd=123456").then(data => data.text()).then(
data => {
console.log(data);
});

  (3).Post请求同样分两种,表单提交和json提交,需要在headers设置 Content-Type类型。

代码如下:

                        //表单提交
fetch('https://localhost:44387/api/First/Login3', {
method: 'post',
body: 'userName=ypf&pwd=123456',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
})
.then(function(data) {
return data.text();
}).then(function(data) {
console.log(data)
});
//JSON提交
fetch('https://localhost:44387/api/First/Login2', {
method: 'post',
body: JSON.stringify({
userName: "admin",
pwd: "123456"
}),
headers: {
'Content-Type': 'application/json',
'token': 'dsfsdf',
}
})
.then(function(data) {
return data.text();
}).then(function(data) {
console.log(data)
});

  (4).如何处理请求错误?

  根据上面的通用格式,肯定是在catch中处理,但是fetch返回的promise对于404、415、500这些错误是获取不到,进入不到catch,catch仅能获取由于网络延迟错误,所以这里需要再次封装一下,获取这些状态,进行throw抛出,让其进入catch即可。 案例如下:

                         //处理非网络错误导致的 错误
fetch("https://localhost:44387/api/First/GetInfor3?userName=ypf&pwd=123456").then(function(response) {
console.log(response);
if (response.status >= 200 && response.status < 300) {
return response;
}
const error = new Error(response.statusText);
error.response = response;
throw error; //检测到报错会进入到catch中
}).then(function(data) {
return data.text();
}).then(function(data) {
console.log(data);
}).catch(function(error) {
console.log(error.response.status + '--' + error.response.statusText);
console.log('There has been a problem with your fetch operation: ', error.message);
});

PS: put和delete用法和post类似,这里不再演示。

3.返回数据的处理

  (1).text():返回的数据是字符串,如果服务器端返回的是json,而这里用text接收,再下一个then里使用的时候需要转换一下,JSON.parse(data)。

  (2).json():返回的数据直接转换成JOSN,后面直接使用即可。

  (3).其它:arrayBuffer()、blob()、formData()。

代码分享:

   //返回的数据是JSON格式的, 如果用data.text()接收,需要JSON.parse(data);转换一下
fetch("https://localhost:44387/api/Third/GetInfor4?userName=ypf&pwd=123456").then(function(data) {
return data.text();
}).then(function(data) {
var myData = JSON.parse(data);
console.log(myData.userName + '--' + myData.pwd);
})
//返回的数据是JSON格式的, 如果用data.json()接收,直接使用即可
fetch("https://localhost:44387/api/Third/GetInfor4?userName=ypf&pwd=123456").then(function(data) {
return data.json();
}).then(function(data) {
console.log(data.userName + '--' + data.pwd);
})

4.其它参数详细配置

  (1).method: 请求使用的方法,如 GET、POST, 默认是Get。

  (2).headers: 请求的头信息,比如可以在里面设置Token、设置content-type类型。

  (3).credentials: 请求的 credentials,如 omit、same-origin 或者 include。为了在当前域名内自动发送 cookie , 必须提供这个选项, 从 Chrome 50 开始,这个属性也可以接受 FederatedCredential 实例或是一个 PasswordCredential 实例。

  (4). mode: 请求的模式,如 cors、 no-cors 或者 same-origin(默认值)。

  (5).body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。

  (6).cache: 请求的 cache 模式: default 、 no-store 、 reload 、 no-cache 、 force-cache 或者 only-if-cached 。

  (7).redirect: 可用的 redirect 模式: follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误), 或者 manual (手动处理重定向). 在Chrome中,Chrome 47之前的默认值是 follow,从 Chrome 47开始是 manual。

  (8).referrer: 一个 USVString 可以是 no-referrer、client或一个 URL。默认是 client。

  (9).referrerPolicy: 指定了HTTP头部referer字段的值。可能为以下值之一: no-referrer、 no-referrer-when-downgrade、 origin、 origin-when-cross-origin、 unsafe-url 。

  (10).integrity: 包括请求的 subresource integrity 值 ( 例如: sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=)。

分析总结:

  (1). fetch发送请求默认是不发送cookie的,不管是同域还是跨域;那么问题就来了,对于那些需要权限验证的请求就可能无法正常获取数据,这时可以配置其credentials项,其有3个值:

    A.omit: 默认值,忽略cookie的发送

    B.same-origin: 表示cookie只能同域发送,不能跨域发送

    C.include: cookie既可以同域发送,也可以跨域发送

  PS:fetch默认对服务端通过Set-Cookie头设置的cookie也会忽略,若想选择接受来自服务端的cookie信息,也必须要配置credentials选项;

  (2). fetch不支持超时timeout处理

  (3). fetch不支持JSONP。目前比较成熟的开源JSONP实现fetch-jsonp给我们提供了解决方案,想了解可以自行前往。(https://github.com/camsong/fetch-jsonp)

  (4). 与XHR2一样,fetch也是支持跨域请求的,只不过其跨域请求做法与XHR2一样,需要客户端与服务端支持;另外,fetch还支持一种跨域,不需要服务器支持的形式,具体可以通过其mode的配置项来说明。

    A.same-origin:该模式是不允许跨域的,它需要遵守同源策略,否则浏览器会返回一个error告知不能跨域;其对应的response type为basic。

    B.cors: 该模式支持跨域请求,顾名思义它是以CORS的形式跨域;当然该模式也可以同域请求不需要后端额外的CORS支持;其对应的response type为cors。

    C.no-cors: 该模式用于跨域请求但是服务器不带CORS响应头,也就是服务端不支持CORS;这也是fetch的特殊跨域请求方式;其对应的response type为opaque。(重点!!!)

  特别注意:no-cors该模式允许浏览器发送本次跨域请求,但是不能访问响应返回的内容(能访问通接口,但是不能拿到返回值),这也是其response type为opaque透明的原因。

                        //特殊跨域不需要服务器端进行设置,能访问通,但是拿不到响应结果
fetch('https://localhost:44387/api/First/Login3', {
method: 'post',
body: 'userName=ypf&pwd=123456',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
mode: 'no-cors'
})
.then(function(data) {
return data.text();
}).then(function(data) {
console.log(data)
});

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 

第五节: 前后端交互之Promise用法和Fetch用法的更多相关文章

  1. Servlet实现前后端交互的原理及过程解析

    在日常调试项目时,总是利用tomcat去启动项目,并进行前后端联调,但对于前后端的请求响应的交互原理及过程并不是特别清晰. 为什么在前端发出相应请求,就能跳转到后端通过程序得到结果再响应到前端页面呢? ...

  2. js前后端交互

    1.前后端交互模式 2.promise用法 (1)异步调用 (2)ajax回顾 (3).promise 优点:可以解决回调地狱(多层异步调用嵌套问题)(解决代码可读性低的问题) 提供简洁的api (4 ...

  3. 三、vue前后端交互(轻松入门vue)

    轻松入门vue系列 Vue前后端交互 六.Vue前后端交互 1. 前后端交互模式 2. Promise的相关概念和用法 Promise基本用法 then参数中的函数返回值 基于Promise处理多个A ...

  4. Node之简单的前后端交互

    node是前端必学的一门技能,我们都知道node是用的js做后端,在学习node之前我们有必要明白node是如何实现前后端交互的. 这里写了一个简单的通过原生ajax与node实现的一个交互,刚刚学n ...

  5. Django之META与前后端交互

    Django之META与前后端交互 1 提交表单之GET 前端提交数据与发送 1)提交表单数据 2)提交JSON数据 后端的数据接收与响应 1)接收GET请求数据 2)接收POST请求数据 3)响应请 ...

  6. 前后端交互实现(nginx,json,以及datatable的问题相关)

    1.同源问题解决 首先,在同一个域下搭建网络域名访问,需要nginx软件,下载之后修改部分配置 然后再终端下cmd  nginx.exe命令,或者打开nginx.exe文件,会运行nginx一闪而过, ...

  7. springboot+mybatis+thymeleaf项目搭建及前后端交互

    前言 spring boot简化了spring的开发, 开发人员在开发过程中省去了大量的配置, 方便开发人员后期维护. 使用spring boot可以快速的开发出restful风格微服务架构. 本文将 ...

  8. 百度ueditor的图片上传,前后端交互使用

    百度ueditor的使用 一个文本编辑器,看了网上很多文档写的很乱,这里拾人牙慧,整理下怎么使用. 这个东西如果不涉及到图片附件上传,其实很简单,就是几个前端文件,直接引用,然后配置下ueditor. ...

  9. SSM-网站后台管理系统制作(4)---Ajax前后端交互

    前提:Ajax本身就为前后端交互服务的,实现功能:用户输入信息,实时判断用户的情况,这也是现在登录界面普遍流行的做法.前端js通过注释识别Controller层,该层查询返回,和之前Google验证码 ...

随机推荐

  1. 根据ID选中

    var name = document.getElementsById("mainStack");

  2. 【转】Java(多)线程中注入Spring的Bean

    问题说明 今天在web应用中用到了Java多线程的技术来并发处理一些业务,但在执行时一直会报NullPointerException的错误,问题定位了一下发现是线程中的Spring bean没有被注入 ...

  3. SSM项目集成Lucene+IKAnalyzer在Junit单元测试中执行异常

    个人博客 地址:http://www.wenhaofan.com/article/20181108132519 问题描述 在项目运行以及main方法中能够正常运行,但是使用junit单元测试时却报如下 ...

  4. Oracle 中的 Incarnation 到底是个什么?概念理解篇

    高中时候,我深深“爱”上了一位女孩子.那个年纪确实不懂什么是真正的“爱”,反正每天满脑子都是她,只要见到她就会紧张和激动,确切的说是深深的喜欢.你告诉我这叫初恋?不,我的初恋应该是小学3年级,三六班. ...

  5. linux分区命令parted的用法

    parted的适用场景 创建操作大于2T的分区 一般情况下,我们都是选择使用fdisk工具来进行分区,但是目前在实际生产环境中使用的磁盘空间越来越大,呈TiB级别增长:而常用的fdisk这个工具对分区 ...

  6. 开放系统互联(OSI)模型

    开放系统互联(OSI)模型 是由国际标准化组织(ISO)于1984年提出的一种标准参考模型,是一种关于由不同供应商提供的不同设备和应用软件之间的网络通信的概念性框架结构.它被公认为是计算机通信和 in ...

  7. thinkphp中如何用路由调用前台html界面

    先上图片看看基本的文件位置 1.首先在application\route.php中定义路由 <?php use think\Route; Route::get("home", ...

  8. Windows DOS下查看硬盘分区

    运行cmd Diskpart //加载 list Disk //列出硬盘 list Volume //列出分区 Select Disk //选择 编号0的硬盘 list Partition //列出当 ...

  9. OWASP安装

    下载网址:https://sourceforge.net/projects/owaspbwa/files/1.0rc2/ 下载完之后解压 解压之后 打开虚拟机 然后 虚拟机中菜单栏 文件---打开-- ...

  10. CSS的长度单位

    对于css的长度单位真的有必要知道一下.那么css长度单位有哪些呢? 分成两大类: 1.绝对单位:不会因为其他元素的尺寸变化而变化.坚持自我. 2.相对单位:没有一个确定的值,而是由其他元素的尺寸影响 ...