网络基础与promise(更新)

网络基础

网络

1.从用户输入网址到页面渲染,这个流程发生了什么?
  1. 输入网址,按下回车,浏览器进行网络请求
    1. 首先浏览器对输入的网址进行DNS解析,通过域名查询到具体的IP。
    2. 进行TCP三次握手建立连接
    3. TLS握手(TLS握手是HTTPS协议的流程,通过TLS握手,客户端和服务器确认使用的加密算法以及会话密钥)
    4. 浏览器获取到HTML文件
  2. 浏览器开始解析HTML文件
    1. 在浏览器解析文件的过程中,遇到网络请求(如src,link等)会再次发起网络请求
    2. 解析成功后会先根据HTML代码构建DOM树,根据CSS构建CSSOM树。
    3. 遇到script标签,会判断是否存在async或者defer,存在async时,会先下载并执行JS,存在defer会先下载文件,等HTML解析完成后按顺序执行JS代码。如果都不存在,则会阻塞渲染流程,等JS执行完毕。
  3. CSSOM树和DOM树构建完成后会开始生成Render树,然后浏览器调用GPU绘制,合成图层,将内容显示在屏幕上。
2.名词解释
  • DNS解析:DNS的作用是通过域名查询到具体的IP。因为IP存在数字和英文的组合,不利于记忆,所以出现了域名。域名相当于某个IP的别名,DNS就是去查询这个别名的真正名称。在TCP握手之前就进行了DNS查询,这个查询是操作系统自己做的。当浏览器想访问www.google.com时,会进行以下操作:

    • 操作系统会首先在本地缓存中查询 IP

    • 没有的话会去系统配置的 DNS 服务器中查询.

    • 如果这时候还没得话,会直接去 DNS 根服务器查询,这一步查询会找出负责com这个一级域名的服务器

    • 然后去该服务器查询google这个二级域名

    • 接下来三级域名的查询其实是我们配置的,你可以给www这个域名配置一个 IP,然后还可以给别的三级域名配置一个 IP

      以上介绍的是 DNS 迭代查询,还有种是递归查询,区别就是前者是由客户端去做请求,后者是由系统配置的 DNS 服务器做请求,得到结果后将数据返回给客户端。

    • 递归查询:客户机向本地DNS服务器发起请求,然后等待一个确定的结果。本地DNS服务器向其他DNS服务器发起请求,直到查询到结果,再转交给客户端。

    • 迭代查询:客户机向DNS服务器发起请求,若该DNS服务器没有查询到结果,则向客户机返回另一台DNS服务器的地址,客户机向新的DNS服务器发起新的请求。直到得到结果。

  • 什么是TCP/IP协议:不同硬件、操作系统之间的通信,所有的一切都需要一种规则,我们就把这种规则称为协议(protocol)。协议中存在各种各样的内容。从电缆的规格到IP地址的选定方式、寻找异地用户的方法、双方建立通信的顺序,以及Web页面显示需要处理的步骤等。像这样把与互联网相关联的协议集合起来总称为 TCP/IP 。也有说法认为,TCP/IP是指TCP和IP这两种协议。还有一种说法认为,TCP/IP是在IP协议的通信过程中,使用到的协议族的统称。

  • TCP/IP协议的层级:TCP/IP协议族最重要的一点就是分层,TCP/IP协议族按层次分为了4层:应用层、传输层、网络层、数据链路层。

  • TCP协议的三次握手:

    在这之前需要了解一个重要的性能指标 RTT。该指标表示发送端发送数据到接收到对端数据所需的往返时间。
    
    建立连接三次握手
    
    首先假设主动发起请求的一端称为客户端,被动连接的一端称为服务端。不管是客户端还是服务端,TCP 连接建立完后都能发送和接收数据,所以 TCP 是一个全双工的协议。
    
    起初,两端都为 CLOSED 状态。在通信开始前,双方都会创建 TCB。 服务器创建完 TCB 后便进入 LISTEN 状态,此时开始等待客户端发送数据。
    
    第一次握手
    
    客户端向服务端发送连接请求报文段。该报文段中包含自身的数据通讯初始序号。请求发送后,客户端便进入 SYN-SENT 状态。
    
    第二次握手
    
    服务端收到连接请求报文段后,如果同意连接,则会发送一个应答,该应答中也会包含自身的数据通讯初始序号,发送完成后便进入 SYN-RECEIVED 状态。
    
    第三次握手
    
    当客户端收到连接同意的应答后,还要向服务端发送一个确认报文。客户端发完这个报文段后便进入 ESTABLISHED 状态,服务端收到这个应答后也进入 ESTABLISHED 状态,此时连接建立成功。
    
    PS:第三次握手中可以包含数据,通过快速打开(TFO)技术就可以实现这一功能。其实只要涉及到握手的协议,都可以使用类似 TFO 的方式,客户端和服务端存储相同的 cookie,下次握手时发出 cookie 达到减少 RTT 的目的。
    
    
  • 为什么TCP协议需要三次握手,两次握手就可以建立连接。

    • 因为这是为了防止出现失效的连接请求报文段被服务端接收的情况,从而产生错误。

      可以想象如下场景。客户端发送了一个连接请求 A,但是因为网络原因造成了超时,这时 TCP 会启动超时重传的机制再次发送一个连接请求 B。此时请求顺利到达服务端,服务端应答完就建立了请求,然后接收数据后释放了连接。

      假设这时候连接请求 A 在两端关闭后终于抵达了服务端,那么此时服务端会认为客户端又需要建立 TCP 连接,从而应答了该请求并进入 ESTABLISHED 状态。但是客户端其实是 CLOSED 的状态,那么就会导致服务端一直等待,造成资源的浪费。

      PS:在建立连接中,任意一端掉线,TCP 都会重发 SYN 包,一般会重试五次,在建立连接中可能会遇到 SYN Flood 攻击。遇到这种情况你可以选择调低重试次数或者干脆在不能处理的情况下拒绝请求。

  • 断开连接,四次挥手:

    TCP 是全双工的,在断开连接时两端都需要发送 FIN 和 ACK。
    
    第一次握手
    
    若客户端 A 认为数据发送完成,则它需要向服务端 B 发送连接释放请求。
    
    第二次握手
    
    B 收到连接释放请求后,会告诉应用层要释放 TCP 链接。然后会发送 ACK 包,并进入 CLOSE_WAIT 状态,此时表明 A 到 B 的连接已经释放,不再接收 A 发的数据了。但是因为 TCP 连接是双向的,所以 B 仍旧可以发送数据给 A。
    
    第三次握手
    
    B 如果此时还有没发完的数据会继续发送,完毕后会向 A 发送连接释放请求,然后 B 便进入 LAST-ACK 状态。
    
    PS:通过延迟确认的技术(通常有时间限制,否则对方会误认为需要重传),可以将第二次和第三次握手合并,延迟 ACK 包的发送。
    
    第四次握手
    
    A 收到释放请求后,向 B 发送确认应答,此时 A 进入 TIME-WAIT 状态。该状态会持续 2MSL(最大段生存期,指报文段在网络中生存的时间,超时会被抛弃) 时间,若该时间段内没有 B 的重发请求的话,就进入 CLOSED 状态。当 B 收到确认应答后,也便进入 CLOSED 状态。
    
    为什么 A 要进入 TIME-WAIT 状态,等待 2MSL 时间后才进入 CLOSED 状态?
    
    为了保证 B 能收到 A 的确认应答。若 A 发完确认应答后直接进入 CLOSED 状态,如果确认应答因为网络问题一直没有到达,那么会造成 B 不能正常关闭。
    
    
  • TLS握手:SSL 和 TLS 协议可以为通信双方提供识别和认证通道,从而保证通信的机密性和数据完整性。TLS 协议是从Netscape SSL 3.0协议演变而来的,不过这两种协议并不兼容,SSL 已经被 TLS 取代,所以下文就以 TLS 指代安全层。 TLS 握手是启动 HTTPS 通信的过程,类似于 TCP 建立连接时的三次握手。 在 TLS 握手的过程中,通信双方交换消息以相互验证,相互确认,并确立它们所要使用的加密算法以及会话密钥 (用于对称加密的密钥)。可以说,TLS 握手是 HTTPS 通信的基础部分。

    TLS握手的流程:

    • 商定双方通信所使用的的 TLS 版本 (例如 TLS1.0, 1.2, 1.3等等);
    • 确定双方所要使用的密码组合;
    • 客户端通过服务器的公钥和数字证书 (上篇文章已有介绍)上的数字签名验证服务端的身份;
    • 生成会话密钥,该密钥将用于握手结束后的对称加密。
3.HTTP状态码
2XX 成功

200 OK,表示从客户端发来的请求在服务器端被正确处理

204 No content,表示请求成功,但响应报文不含实体的主体部分

205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容

206 Partial Content,进行范围请求

3XX 重定向

301 moved permanently,永久性重定向,表示资源已被分配了新的 URL

302 found,临时性重定向,表示资源临时被分配了新的 URL

303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源

304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况

307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求

4XX 客户端错误

400 bad request,请求报文存在语法错误

401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息

403 forbidden,表示对请求资源的访问被服务器拒绝

404 not found,表示在服务器上没有找到请求的资源

5XX 服务器错误

500 internal sever error,表示服务器端在执行请求时发生了错误

501 Not Implemented,表示服务器不支持当前请求所需要的某个功能

503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求

ajax传字段和传文件

//原生ajax请求
 let f=new FormData()//就是表单格式的数据包
			 f.append("touxiang",inpu.files[0])
			 f.append("email","2733xxx@.com")
			
			var xhr=new XMLHttpRequest()||new ActiveXObject("Micsorf.XMLHTTP")
			xhr.open("POST","http://www.baidu.com/login",true)//网络连接配置,没有发网络请
			 xhr.send(JSON.stringify(f))//连接
			
			 xhr.onreadystatechange=function  () {
			 	if(xhr.readyState==4){
			 		xhr.responseText
			 	}
			 }

axios发送字段和文件:

	//axios传字段
			axios(url,{params:{pwd:123,username:"karen"}})//get请求
			axios.post(url,{pwd:123,username:"karen"})//post请求
			axios({
				url:"",
				
			})
			
			
	//axios传文件
			 let f=new FormData()//就是表单格式的数据包
			 f.append("touxiang",inpu.files[0])
			 f.append("email","2733xxx@.com")
			 axios.post(url,f)

后端接收:

//后端接受文件
			//node原生代码
			// let total=""
			// req.on("data",(str)=>{
			// 	total+=str
			// })
			// req.on("end",()=>{
			// 	console.log(total)
			// })
			// egg.js框架:
			// this.ctx.request.files==>前提 配置文件中打开文件上传模式,csrf(配置跨域)
			
			//后端接受字段
			// egg:
			//this.ctx.requet.body(post请求)
			//this.ctx.requet.query(get请求)
			
			
			//后端发送字段给前端
			//node原生代码
			//res.write(二进制或者字符串)
			//res.end(二进制或者字符串)
			
			// egg
			// this.ctx.body=[]//{},string,number
			//会转化为字符串给前端

前端所有能发送网络请求的方式:

// 浏览器地址栏: 只能发送get 得到的数据使用是用浏览器的工具去解析(字符串,html,文件编码,image,video)
//浏览器不能解析的数据包 浏览器就会下载到默认下载路径
			
			//link-href  get  得到的数据包按照标签的功能解析
			
			//src get 网络请求资源  得到资源以后 根据标签 v8引擎运行或者图片渲染
			//url get 网络请求资源 
			
			//a-href get  用户点了而且没阻止默认事件 网络请求资源 得到资源以后使用方式同浏览器地址栏
			
			//form get/post/xx 用户点击表单内部的提交按钮或者触发提交事件 
			//打包表单内部的数据,key就是name   value是用户交互的结果
			//按照数据传输方式 由form标签的method属性指定  
			//发送给action后端
			//返回的数据包使用方式同a标签
			
			//ajax  get/post/xx  收到数据以后放在ajax的对象的某个属性中的 让程序员自己操作
			//jsonp==>src  get
			//script可以做网络请(因为跨域的阻止只有ajax)
			//jsonp 'fn({"name":"karen"})'    JSON: '{"name":"karen"}'
			//得到的数据是一个fn函数,在script环境里,就可以执行。
			// function fn(arg){			
			// }
			// <script src="xxx">
			
			//后端:  request  egg=>this.curl  //代理服务器
			
			

promise

promise是ES5末期产生的一种数据容器的技术,它内部会自己产生数据,产生数据的过程可以是同步的也可以是异步的。也可以取出内部的数据使用,取数据的过程是异步的。

promise是JS的内置构造方法,传入该构造方法的回调函数会直接运行。

promise对象通过.then方法来使用其内部的数据。该方法是异步的,且该方法的返回值是一个新的promise对象

new Promise(function fn(n1,n2){
   xhr.open(methd,url,true)
		 xhr.send()
		 xhr.onreadystatechange=()=>{
		if(xhr.readyState==4){
	n1(100)//100就是Promise数据容器内部产生的数据
	}else{
      n2(10)
	}
	 }
}).then((res)=>{
   console.log(res)//打印100
})

	//调then函数传入的回调函数的返回值是Promise对象那么这个新的Promise对象就是它
			//调then函数传入的回调函数的返回值不是Promise对象,那么就会把这个返回值封装为一个新的Promise对象返回

promise具有三种状态:pending、resolve、reject

它只能从pending转变为resolve(成功)

或者从pending转变为reject(失败)

并且状态不可逆

promise对象通过.catch方法抓取失败的数据,其底层是try{}catch(err){}

使用promise封装axios

function myaxios (url) {
	let p1=new Promise((n1,n2)=>{
		let xhr=new XMLHttpRequest()||ActiveXObject("Micsorf.XMLHTTP")
		xhr.open("GET",url,true)
		xhr.send()
		xhr.onreadystatechange=function() {
			if(xhr.readyState==4){
				if(xhr.status==200){
					n1(xhr.responseText)
				}else if(xhr.status>=400){
					n2(xhr.responseText)
				}
			}
		}		
	})
	
	return p1
}
任务队列

宏任务:script、setTimeout、setInterval、I/O、UI交互事件等等

微任务:promise.then、MutationObserver、process.nextTick(node.js环境)

宏任务比微任务先执行

事件循环:eventloop:

  1. 从宏任务的头部取出一个任务执行;
  2. 执行过程中若遇到微任务则将其添加到微任务的队列中;
  3. 宏任务执行完毕后,微任务的队列中是否存在任务,若存在,则按顺序依次执行,直到执行完毕
  4. GUI渲染;
  5. 回到步骤一,直到宏任务执行完毕。

例题:

console.log(6)
			let p1=new Promise((n1,n2)=>{
				console.log(1)
				let p3=new Promise((n1,n2)=>{
					console.log(22)	
				    n1()
				})
				setTimeout(()=>{
					console.log(3)
					p3.then(()=>{console.log(33)})
				},0)//2宏
				console.log(7)
				n1(4)
			})
			console.log(5)
			p1.then((res)=>{
				console.log(res)
				setTimeout(()=>{
					console.log(8)
				},0)//3宏
				
				return  new Promise((n1,n2)=>{
					console.log(2)					
				})
			})
			//6 1 7 5 4 2 3 8
			
promise的静态方法:
  • Promise.then(()=>{});
  • Promise.catch(()=>{});
  • Promise.all([p1,p2,p3]); //当数组内promise对象都执行成功时,外层promise返回成功
  • Promise.resolve(1000) //等价于==>new Promise((N1,N2)=>{N1(1000)}) //p1.then((res)=>{})
  • Promise.reject(1000) //等价于==>new Promise((N1,N2)=>{N2(1000)}) //p2.catch((res)=>{})
  • Promise.race([p1, p2, p3]); //外层promise的返回值是数组内第一个改变状态的promise对象的返回值

跨域

什么是跨域?

——浏览器的地址栏输入一个url显示出一个HTML网页,网页内部如果有ajax的代码,这个网络请求只有地址栏的url对应的服务器,浏览器才不会阻止,如果页面的url和ajax的url不是同一个服务器,就是跨域。

——浏览器具有同源策略,只有ajax请求会受到跨域限制。

浏览器怎么判断是否同源?

——//http://www.baidu.com ==>http://ip:port —通过DNS解析后,判断协议是否相同,ip地址是否相同,端口是否相同。

什么是同源策略?

——所谓同源指的是“协议+域名+端口”三者相同,即使两个不同的域名指向同一个ip,他们也不是同源的。同源策略(SOP)是一种约定,是浏览器最核心也最基本的安全功能。缺少同源策略,浏览器很容易受到XSS、CSFR等攻击。同源策略是为了安全,确保一个应用中的资源只能被本应用的资源访问。保护本地数据不被JavaScript代码获取的数据污染。浏览器拦截的是服务器返回的数据,即客户端请求成功了,服务器响应了,但是被浏览器拦截了。

跨域解决方案:(开发阶段(dev))

  • CORS
  • JSONP
  • Proxy

CORS

CORS是一个W3C标准,全称是“跨域资源共享”,它允许浏览器向跨域的服务器,发出XMLHttpRequest请求,克服了AJAX只能同源使用的限制。
实现CORS需要在服务器实现CORS接口:
例:
http.createServer((req, res) => {
	var pathname = url.parse(req.url).pathname
	fs.readFile(__dirname + "/src/" + pathname, (err, data) => {
		if (!err) {
			res.end(data.toString())
		} else {
			if (pathname == "/ajax1") {
				res.setHeader("Access-Control-Allow-Origin", "*")//该参数表示允许跨域的地址,“*”表示所有地址。
				res.end('{"name":"karen"}')
			} else if (pathname == "/jsonp1") {
				let cb = querystring.parse(url.parse(req.url).query).cb
				res.end(`${cb}({"name":"jack"})`)
			} else if (pathname == "/baidu") {
				//请求百度页面发送给自己的前端
				let url = "http://www.baidu.com/index.html"
				request(url, (err, data, body) => {
					if (!err) {
						res.end(body)
					}
				})
			}
		}
	})
}).listen(10086)

JSONP:

JSONP本质上是根据script标签没有跨域限制的原理实现的。
在前端创建一个script标签,它的地址是需要跨域的网址,并且创建一个回调函数来接收数据。服务器会响应一个json格式包装的数据(所以这种方式叫做jsonp,即json padding),例如:callback({"name":"jack","age":"15"}),浏览器接收到返回的数据后,会将其作为函数callback调用,并将解析后的json对象作为参数传递,前端则可以在callback函数里处理数据。

JSONP的缺点:只能发送get请求,并且需要服务器返回特定格式的数据,在调用失败时不会返回各种HTTP状态码,且安全性有漏洞,如果返回的JS数据是人为操控的,会导致整个使用JSONP的网站都具有风险。

//代码实现

//前端
	<script>
			function fm() {
				 $.getJSON(url,(res)=>{
				 	console.log(res)
				 })
				 myjq("http://127.0.0.1:8080/jsonp1?cb=", (res) => {
				 	console.log(res)
				 })
				myjq("http://127.0.0.1:8080/jsonp1?sug=", (res) => {
					console.log(res)
				})
			}

//定义实现JSONP的请求函数
			function myjq(url, cb) {
				let callback = "myjq" + new Date().getTime()//避免重名
				window[callback] = (arg) => {
					// console.log(arg)
					cb(arg)
				}
				var sr = document.createElement("script")
				sr.src = url + callback //"http://127.0.0.1:8080/jsonp1?cb="+cb// 'send({"name":"jack"})'
				document.body.appendChild(sr)
			}
		</script>
		
		//服务器
		http.createServer((req, res) => {
	//http://127.0.0.1:8080/car?id=123
	//req.url==>/car?id=123
	var pathname = url.parse(req.url).pathname
	console.log(pathname)
	fs.readFile(__dirname + "/src/" + pathname, (err, data) => {
		if (!err) {
			res.end(data.toString())
		} else {
			if (pathname == "/ajax1") {
				// CORS
				res.setHeader("Access-Control-Allow-Origin", "*")
				res.end('{"name":"karen"}')
				//JSONP
			} else if (pathname == "/jsonp1") {
				let cb = querystring.parse(url.parse(req.url).query).cb
				res.end(`${cb}({"name":"jack"})`)//必须返回特定格式的数据
				
			} else if (pathname == "/baidu") {//代理
				//请求百度页面发送给自己的前端
				let url = "http://www.baidu.com/index.html"
				request(url, (err, data, body) => {
					if (!err) {
						res.end(body)
					}
				})
			} else {
				// res.end("404")
				let url = "https://api.weibo.com"+req.url
				request(url, (err, data, body) => {
					if (!err) {
						res.end(body)
					}
				})
			}
		}

	})

}).listen(10086)

代理:Proxy

//服务器与服务器之间的请求没有跨域的限制,所以浏览器可以向与自己同源的服务器发起请求,由同源服务器向第三方服务器进行请求,获取数据,再返回浏览器。

//服务器发起请求的方式:
	request
	this.curl

//代码实现:
		http.createServer((req, res) => {
	//http://127.0.0.1:8080/car?id=123
	//req.url==>/car?id=123
	var pathname = url.parse(req.url).pathname
	console.log(pathname)
	fs.readFile(__dirname + "/src/" + pathname, (err, data) => {
		if (!err) {
			res.end(data.toString())
		} else {
			if (pathname == "/ajax1") {
				// CORS
				res.setHeader("Access-Control-Allow-Origin", "*")
				res.end('{"name":"karen"}')
				//JSONP
			} else if (pathname == "/jsonp1") {
				let cb = querystring.parse(url.parse(req.url).query).cb
				res.end(`${cb}({"name":"jack"})`)//必须返回特定格式的数据
				
			} else if (pathname == "/baidu") {
			//代理
				//浏览器请求自己的服务器   服务器请求百度页面发送给自己的前端
				let url = "http://www.baidu.com/index.html"
				request(url, (err, data, body) => {
					if (!err) {
						res.end(body)
					}
				})
			} else {
				// res.end("404")
				let url = "https://api.weibo.com"+req.url
				request(url, (err, data, body) => {
					if (!err) {
						res.end(body)
					}
				})
			}
		}

	})

}).listen(10086)


vue的代理配置

//在vue.config.js文件中配置
module.exports={
	lintOnSave:false,
	devServer:{
			port:"8080",
			host:"localhost", 
			//表示当前域名端口下的请求,若路径中包含"/api",服务器会向target配置的目标地址发起请求
			proxy:{
				"/api":{
					target:"http://127.0.0.1:8080",
					changeOrigin:true,
					pathRewrite:{"^/api":""}//替换请求地址中的api字段
				},
				"/api2":{
					target:"http://127.0.0.1:8080",
					changeOrigin:true,
					pathRewrite:{"^/api":""}
				}
			}
		}
}



//使用vue作为服务器发起请求时,在App.vue组件中配置:axios.defaults.baseURL=url,可以使发起的请求路径拼接到该根路径上:
	mounted() {
			// axios("/api/car").then((res)=>{//url/api/car
			// 	console.log(res)
			// })
			// this.$axios(url,{withCredentials:true,params:{id:"11"}})
			//this.$axios.post(url,{id:"11"},{withCredentials:true})
		}

async/await

promise出现之前,如果要实现业务:先请求一个数据,之后再请求另一个数据,会陷入回调地狱。promise出现之后,用promise封装的axios在实现这个业务,不用进行重复的回调,但是代码也不好维护,如:

	// axios()
			axios(url1).then((res1)=>{
				//
				return axios(url2+res1)
			})
			.then((res2)=>{
				//
				return axios(url3+res2)
			})
			.then((res3)=>{
				//
				return axios(url4+res2)
			})
		

ES6出现了指针函数generator,它是一个状态机,封装了多个内部状态,执行该函数,会返回一个遍历器对象,可以使用其内部的next方法依次遍历,generator函数内部的yield表达式可以暂停执行,next可以恢复执行,实现了分步骤阻塞。

async函数是generator函数的语法糖,函数用async标记后,在其内部可以使用await表示其后的表达式需要等待结果。

async function(){
   await axios(url)
}

axios、Jquery、fetch


### ajax axios jQuery fetch这三个网络工具的使用方式?和区别?
 //总结
 Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
 从浏览器中创建 XMLHttpRequests
 从 node.js 创建 http 请求
 支持 Promise API
 拦截请求和响应
 转换请求数据和响应数据
 取消请求
 自动转换 JSON 数据
 客户端支持防御 XSRF
 axios的属性配置:
 {
    // `url` 是用于请求的服务器 URL
   url: '/user',
   // `method` 是创建请求时使用的方法
   method: 'get', // default
   // `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。
   // 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL
   baseURL: 'https://some-domain.com/api/',
   // `transformRequest` 允许在向服务器发送前,修改请求数据
   // 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法
   // 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream
   transformRequest: [function (data, headers) {
     // 对 data 进行任意转换处理
     return data;
   }],
   // `transformResponse` 在传递给 then/catch 前,允许修改响应数据
   transformResponse: [function (data) {
     // 对 data 进行任意转换处理
     return data;
   }],
   // `headers` 是即将被发送的自定义请求头
   headers: {'X-Requested-With': 'XMLHttpRequest'},
   // `params` 是即将与请求一起发送的 URL 参数
   // 必须是一个无格式对象(plain object)或 URLSearchParams 对象
   params: {
     ID: 12345
   },
    // `paramsSerializer` 是一个负责 `params` 序列化的函数
   // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/)
   paramsSerializer: function(params) {
     return Qs.stringify(params, {arrayFormat: 'brackets'})
   },
   // `data` 是作为请求主体被发送的数据
   // 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH'
   // 在没有设置 `transformRequest` 时,必须是以下类型之一:
   // - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams
   // - 浏览器专属:FormData, File, Blob
   // - Node 专属: Stream
   data: {
     firstName: 'Fred'
   },
   // `timeout` 指定请求超时的毫秒数(0 表示无超时时间)
   // 如果请求话费了超过 `timeout` 的时间,请求将被中断
   timeout: 1000,
    // `withCredentials` 表示跨域请求时是否需要使用凭证
   withCredentials: false, // default
   // `adapter` 允许自定义处理请求,以使测试更轻松
   // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)).
   adapter: function (config) {
     /* ... */
   },
  // `auth` 表示应该使用 HTTP 基础验证,并提供凭据
   // 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头
   auth: {
     username: 'janedoe',
     password: 's00pers3cret'
   },
    // `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream'
   responseType: 'json', // default
   // `responseEncoding` indicates encoding to use for decoding responses
   // Note: Ignored for `responseType` of 'stream' or client-side requests
   responseEncoding: 'utf8', // default
    // `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称
   xsrfCookieName: 'XSRF-TOKEN', // default
   // `xsrfHeaderName` is the name of the http header that carries the xsrf token value
   xsrfHeaderName: 'X-XSRF-TOKEN', // default
    // `onUploadProgress` 允许为上传处理进度事件
   onUploadProgress: function (progressEvent) {
     // Do whatever you want with the native progress event
   },
   // `onDownloadProgress` 允许为下载处理进度事件
   onDownloadProgress: function (progressEvent) {
     // 对原生进度事件的处理
   },
    // `maxContentLength` 定义允许的响应内容的最大尺寸
   maxContentLength: 2000,
   // `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject  promise 。如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`),promise 将被 resolve; 否则,promise 将被 rejecte
   validateStatus: function (status) {
     return status >= 200 && status < 300; // default
   },
   // `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目
   // 如果设置为0,将不会 follow 任何重定向
   maxRedirects: 5, // default
   // `socketPath` defines a UNIX Socket to be used in node.js.
   // e.g. '/var/run/docker.sock' to send requests to the docker daemon.
   // Only either `socketPath` or `proxy` can be specified.
   // If both are specified, `socketPath` is used.
   socketPath: null, // default
   // `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。允许像这样配置选项:
   // `keepAlive` 默认没有启用
   httpAgent: new http.Agent({ keepAlive: true }),
   httpsAgent: new https.Agent({ keepAlive: true }),
   // 'proxy' 定义代理服务器的主机名称和端口
   // `auth` 表示 HTTP 基础验证应当用于连接代理,并提供凭据
   // 这将会设置一个 `Proxy-Authorization` 头,覆写掉已有的通过使用 `header` 设置的自定义 `Proxy-Authorization` 头。
   proxy: {
     host: '127.0.0.1',
     port: 9000,
     auth: {
       username: 'mikeymike',
       password: 'rapunz3l'
     }
   },
   
      
      
  Fetch
  fetch()提供了进行跨网络异步请求资源的方式。
  优点:
  		1.语法简洁,更加语义化
      2.基于Promise实现,支持async/await
      3.同构方便
   它不会从服务端发送或者接收cookies。
   
   fetch(url).then((res)=>{
      return res.json();//fetch获得的数据需要调用json()方法来转换为JSON数据
   }).then((data)=>{
      console.log(data)
   })
   

缓存:

###
h5网站前端的存储技术: 离线应用  数据库  缓存技术
 前端缓存(cookie localstorage sessionstorage的区别) 
cookie始终在同源的http请求中携带,即使不需要,cookie在浏览器和服务器中来回传递。而localStorage和sessionStora仅仅在本地存储,不会和服务器通信,也不会自动把数据发送给服务器。
存储大小不同,cookie为4kb左右;localStorage, sessionStorage可以达到5M
数据有效期不同,sessionStorage仅在同源窗口中有效,关闭窗口就消失了,cookie可以设置过期时间,localStorage长期有效
localStorage, sessionStorage有现成的API, cookie需要程序员手动封装

 document.cookie="username=karen;expice=123455"
 let a=document.cookie
 
 localstorage.setItem("k1","value")
 localstorage.setItem("k2","value2")
 localstorage.setItem("k2",null)
 localstorage.getItem("k1")
 
 sessionstorage.setItem("k1","value")
 sessionstorage.setItem("k2","value2")
 sessionstorage.setItem("k2",null)
 sessionstorage.getItem("k1")
 
 
 
egg后端的缓存技术:后端cookie session


上一篇:万字长文带你了解Promise


下一篇:promise学习---改变 promise 状态和指定回调函数的先后