第五节: 前后端交互之Promise用法和Fetch用法
一. 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用法的更多相关文章
- Servlet实现前后端交互的原理及过程解析
在日常调试项目时,总是利用tomcat去启动项目,并进行前后端联调,但对于前后端的请求响应的交互原理及过程并不是特别清晰. 为什么在前端发出相应请求,就能跳转到后端通过程序得到结果再响应到前端页面呢? ...
- js前后端交互
1.前后端交互模式 2.promise用法 (1)异步调用 (2)ajax回顾 (3).promise 优点:可以解决回调地狱(多层异步调用嵌套问题)(解决代码可读性低的问题) 提供简洁的api (4 ...
- 三、vue前后端交互(轻松入门vue)
轻松入门vue系列 Vue前后端交互 六.Vue前后端交互 1. 前后端交互模式 2. Promise的相关概念和用法 Promise基本用法 then参数中的函数返回值 基于Promise处理多个A ...
- Node之简单的前后端交互
node是前端必学的一门技能,我们都知道node是用的js做后端,在学习node之前我们有必要明白node是如何实现前后端交互的. 这里写了一个简单的通过原生ajax与node实现的一个交互,刚刚学n ...
- Django之META与前后端交互
Django之META与前后端交互 1 提交表单之GET 前端提交数据与发送 1)提交表单数据 2)提交JSON数据 后端的数据接收与响应 1)接收GET请求数据 2)接收POST请求数据 3)响应请 ...
- 前后端交互实现(nginx,json,以及datatable的问题相关)
1.同源问题解决 首先,在同一个域下搭建网络域名访问,需要nginx软件,下载之后修改部分配置 然后再终端下cmd nginx.exe命令,或者打开nginx.exe文件,会运行nginx一闪而过, ...
- springboot+mybatis+thymeleaf项目搭建及前后端交互
前言 spring boot简化了spring的开发, 开发人员在开发过程中省去了大量的配置, 方便开发人员后期维护. 使用spring boot可以快速的开发出restful风格微服务架构. 本文将 ...
- 百度ueditor的图片上传,前后端交互使用
百度ueditor的使用 一个文本编辑器,看了网上很多文档写的很乱,这里拾人牙慧,整理下怎么使用. 这个东西如果不涉及到图片附件上传,其实很简单,就是几个前端文件,直接引用,然后配置下ueditor. ...
- SSM-网站后台管理系统制作(4)---Ajax前后端交互
前提:Ajax本身就为前后端交互服务的,实现功能:用户输入信息,实时判断用户的情况,这也是现在登录界面普遍流行的做法.前端js通过注释识别Controller层,该层查询返回,和之前Google验证码 ...
随机推荐
- C++——指针2-指向数组的指针和指针数组
7.4 指向数组元素的指针 声明与赋值 例:int a[10], *pa; pa=&a[0]; 或 pa=a[p1] ; 通过指针引用数组元素,经过上述声明及赋值后: *pa就是a[0],*( ...
- EF的预先加载--Eager Loading
预先加载 在对一种类型的实体进行查询时,将相关的实体作为查询的一部分一起加载.预先加载可以使用Include()方法实现. 在此需要说明的是:EF中有两种表关联的方法,一种是Join()方法,一种是I ...
- Allegro 反射仿真--拓扑结构的提取提取及波形分析
在SPECCTRAQuest下,选择Analyze->SI/EMI sim->Probe,进入如下图所示界面: 注:BRD文件命名不用使用中文字符及一些不常用的字符,如".&qu ...
- 11g RAC添加用户表空间(数据文件)至文件系统(File System)的修正
前提:非TEMP.UNDO和SYSTEM表空间,这仨是大爷,您得搂着点.来自博客园AskScuti .客户是添加临时表空间数据文件时,不小心 ADD 到了文件系统中,然后发现,后悔了,还在OS层面 R ...
- 【转】mathnet 使用方法介绍
转载自:http://blog.csdn.net/c914620529/article/details/50393223 在C#中使用mathnet,需要利用using引入相关类 矩阵运算的相关类: ...
- STL-C - 稳定排序
C - 稳定排序 大家都知道,快速排序是不稳定的排序方法.如果对于数组中出现的任意a[i],a[j](i<j),其中a[i]==a[j],在进行排序以后a[i]一定出现在a[j]之前,则认为该排 ...
- HTML连载61-焦点图、固定定位
一.焦点图 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- 大数据-es(elasticsearch)
elasticsearch elasticsearch是lucene作为核心的实时分布式检索,底层使用倒排索引实现. 倒排索引原理 索引表中的每一项都包括一个属性值和具有该属性值的各记录的地址.由于不 ...
- SQLServer使用链接服务器远程查询
--创建链接服务器 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' exec sp_addlinkedsrvlogi ...
- ftp的相关配置
参考 https://www.cnblogs.com/hexige/p/7809481.html 访问参数