一. 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. JFinalSwagger插件

    个人博客 地址:http://www.wenhaofan.com/article/20190304101839 jfinal使用swagger的极简插件 码云地址:https://gitee.com/ ...

  2. path('<int:question_id>/vote/', views.vote, name='vote')中的<int:question_id>的含义

    path('<int:question_id>/vote/', views.vote, name='vote')<int:question_id>用于匹配URL的值,并将扑捉到 ...

  3. Windows ThinPC 7 部署后续设置与本地化

    还原注销背景 %system32%\oobe\info\backgrounds 删除该目录下所有文件后变为wes7背景 24时制与非UNICODE字符乱码解决 Control Panel \ Regi ...

  4. 纯css实现移动端横向滑动列表(可应用于ionic3移动app开发)

    前几天在公司做开发的时候碰到一个列表横向滑动的功能,当时用了iscroll做,结果导致手指触到列表的范围内竖向滑动屏幕滑动不了的问题. 这个问题不知道iscroll本身能不能解决,当时选择了换一种方式 ...

  5. promise是怎么来的?

    一.promise是如何产生的 1. promise并不是一个新的功能,它是一个类,它只是对 异步编程的代码进行整合,它是解决异步(层层嵌套的这种关系),让你的代码看起来更简洁. 2. 在 es6 中 ...

  6. 2019-08-07 纪中NOIP模拟B组

    T1 [JZOJ1385] 直角三角形 题目描述 二维平面坐标系中有N个位置不同的点. 从N个点选择3个点,问有多少选法使得这3个点形成直角三角形. 数据范围 $3 \leq N \leq 1500$ ...

  7. php设计模式之策略模式实例代码

    html <html> <head> <meta charset="UTF-8"> <title>简单计算器</title&g ...

  8. 剑指offer 面试题52. 两个链表的第一个公共节点

    这题之前leetcode做过,权当复习 首先这题没说是否一定有公共节点,如果代码可能因为这一点造成死循环的,需要提前验证所给两个链表是否有公共节点. 方法1:对于每一个list1的节点,遍历list2 ...

  9. 利用Python数据分析基础

    一.Numpy的ndarray:一种多维数组 ndarray是一个通用的同构多维数据容器,其所有元素必须是相同的类型.每个数组都有一个shape(一个表示各维度的元组)和dtype(一个用于说明数据数 ...

  10. python面试的100题(6)

    7.请反转字符串 "aStr"? print("aStr"[::-1]) python实现字符串反转 第一种:使用字符串切片 result = s[::-1] ...