HTTP协议/tpc协议/socket与ajax
Published by Shangyu Liu,
网络协议:标准的osi7层模型并不在实际中使用,实际使用的是5层模型,物理层,数据链路层、网络层,传输层,应用层,重要的是上三层,对应的协议分别是ip协议、tcp协议、http等协议,不同层将上层的数据分割成小块,块头块尾打上标记,直到最底层就变成了01串,每层的格式不同,作用各异,比如ip协议就是寻找路由,在漫漫的物理互联网络中找到请求、应答双方的物理路径。
我目前所使用的数据交互都是http协议的,只能是“请求-响应"模式,server无法主动向client发送信息。
HTTP协议的请求报文被封装好,在传输层分割成块传送,tcp协议负责分割,此外tcp负责数据传输是有连接的。对于一个html网页,本身网页的传送是http请求,网页内所有的img/script/css等还有src属性的的标签都会触发http请求,不同的浏览器http并行个数不同(ie:2,others:6?),每次连接会在数据传输外有额外的时间开销(三次握手),所以尽量减少连接个数和次数(http1.1长连接,默认keep-alive为true)。
HTTP协议:
1、报文,客户端发出请求报文,服务器发出响应报文,
请求报文三部分,请求行、请求首部(两者合并称报文首部)、请求体,请求行指定方法、请求地址(server地址)、协议版本。
请求行:
a、方法:get、post、put、delete、head、trace、options、connect。get没有请求体,即向服务器发送的数据只能包含在url参数中;post有请求体,向服务器发送的数据在请求体中,对服务器而言,后者是安全的,因为不会改变服务器数据。head与get的不同在于返回的应答报文没有应答体,只有应答头,是测试服务器与客户端连接状态的。
b、地址:url
c、协议版本,http1.1/2默认为长连接,http1.0默认每次http请求都要三次握手,长连接需要手动指定
请求首部(还有响应首部、通用首部,实体首部):
是一些键值对,每个键值对占一行,用于通知服务器,这个客户端的一些信息,节选几个常见的首部字段
1)Content-Type:html/text,这说明报文主题是html类型。
2)Keep-Alive: timeout=15,max=100 超时为15s,最大连接数100次
3)待补充
请求体,也就是向服务器发送的信息了。
响应报文三部分,状态行、响应首部(合称报文首部)、响应体
状态行
协议版本、状态码、原因短语
状态码三位,分别是1——5开头
1xx:接受的请求正在处理
2xx:正常返回信息
3xx:重定向状态码,需要额外操作,比如发起向重定向资源的http请求
4xx:客户端请求信息有误,服务器根本不理睬无效请求(如404,找不到请求页面)
5xx:服务器错误,请求内容处理不了。
响应首部
包含服务器的一些信息
响应体
返回请求的数据结果。
TCP协议
主要掌握三次握手确保连接,三次握手的次数解释:
要确保连接,要排除并告知client和server四个状态:a客户端是哑巴、b客户端是聋子、c服务端是哑巴、d服务端是聋子
第一次握手,客户端发送正常、服务端接收正常,server确定a、d状态排除,client什么也没排除
第二次握手,客户端接收正常,证明上一次握手客户端发送正常、服务端接收正常、且服务端发送正常客户端接收正常,client排除a、b、c、d,服务端仍然只能排除状态a、d
第三次握手,服务端接收正常,证明上一次握手客户端接收正常,server今儿排除状态b、c,即a、b、c、d,至此,双方确认,四个状态都排除,开始传输数据。
当然除了三次握手,TCP负责了第一步的数据分割,数据包是一份一份发送的,而且,由于服务端收取和客户端发送的频率不同,防止快的一方淹没慢的一方,所以还有流量调控的左右,此外,还有校验修正错误的作用
IP协议
TCP包会继续被拆成IP包,IP协议会在实体网络上找到连通client和server的路由,这样的路由未必有一条,各个IP包未必经过同一条路由传送(根据网络阻塞情况变化轨道),到达先后顺序未必符合出发的顺序,所以需要按照ip头拼起来,再按照tcp头拼起来,形成完整的http报文。
socket
socket不是协议,而是协议与协议之间的接口,它负责了不同层次的协议之间的数据接口,这样使得协议内部发生改变没关系,只要接口处的数据类型不变,则协议与协议之间是不会相互影响的。
ajax
重头戏,异步的js、xml请求,只更新部分页面数据,而不是刷新整个页面
原生的js有ajax的方法:XMLHttpRequest,用法如下:
请求
1、new一个XHR对象
2、调用对象的open方法,参数:method、url、async,前两项对应请求头
3、setRequestHeader,设置请求首部,对于get方法可以不设置,因为没有请求体呀。
4、send,发送请求
响应
1、responseText/responseXML,返回相应数据(字符串、xml,json的话用第一种)
2、status、statusText,数字、文本形式返回HTTP状态码
3、getAllResponseHeader、getAllResponseHeader,获取全部/某个响应报头
异步
ajax是异步的,所以如何知道数据返回了呢,采用的是事件监听,给xhr绑定onreadystatechange处理函数,监听对象的readyState属性,有五个状态码:
0:请求未初始化,即open方法未调用
1:连接建立,open已经调用
2:请求已接受
3:请求处理中
4:响应完成
则正确返回请求数据的是:readyState==4,status==200
在与php交互时,post方法的send直接写成参数格式(键名=值&键名=值&...)传送,服务端$_POST[“键名"]就可以了,当然要设置下content-type(xhtobj.setRequestHeader)。
xhr的封装,jquery中有完美的封装,把ajax做成一个方法,调用的时候回调函数做参数传入,这需要在定义ajax函数体时候,写上对readyState、status的监听(onreadystatechange)。关于函数做参数、回调函数的问题,另行讨论(挖坑待填)。
json
json从服务器端返回,用JSON.parse(data)就转化为json对象了,注意,要设置content-type为json(响应报文)
从json可以引申出jsonp,这就引出了一个新的话题,跨域问题,另一篇文章会详细介绍不同的跨域方法(坑已填)