参考文章
CSDN关于HTTP : 所有内容皆来自于这两篇文章,只是加上了个人的总结和理解
掘金关于Ajax
原生ajax封装
HTTP
HTTP请求的相应步骤:
- 建立TCP连接
- Web浏览器向Web服务器发送请求,通过url
- Web浏览器发送请求头信息,通过POST/GET/HEAD…
- Web服务器应答头信息
- Web服务器向浏览器发送数据,以Content-Type应答头信息所描述的JSON/JSONP格式…发送用户请求的数据
- 关闭TCP
TC/IP协议
- 链路层:数据接口层或网络接口层,主要处理计算机和网络接口的物理接口细节,使用特殊的协议来转换IP层和网络接口层使用的地址
- 网络层:ICMP协议,IP协议,IGMP协议。IP协议提供不可靠的服务,不可靠服务指的是,可能存在传输错误设置被恶意篡改的情况,所以需要上层的TCP提供可靠的服务。
- 运输层:TCP协议/UDP协议
- 应用层:决定了向用户提供应用服务时通信的活动。
PS: 当数据用TCP传送数据时,数据被送入协议栈中,一层一层的对收到的数据,加上一些首部信息。然后服务器收到请求后,数据就从协议栈中由底层上升,一层一层的去掉协议上的报文首部。
TCP三次握手:同步连接双方的序列号和确认号并交换TCP
1.第一次握手:建立连接。客户端发送连接请求报文段,然后客户端进入SYN_SEND状态,等待服务器的确认。
2. 第二次握手:服务器接收到SYN报文段。接收后,发送SYN+ACK报文段给客户端,此时服务器进入SYN_RECV状态。
3. 第三次握手:客户端收到服务器的报文段,然后再向服务器发送ACK报文段,完毕后,客户端和服务端进入ESTABLISHED装填,完成TCP三次握手。
PS:为什么要进行三次握手,为了防止已经失效的连接请求报文段突然有传送到了服务端。比如,客户端发送了第一个连接请求,在某个网络结点长时间滞留,直到已经失效了以后再到达了服务端,但服务端接收到了以后以为客户端发送了一个新的请求,如果不进行三次握手,那么服务器端确认连接,那么新的连接就建立了。所以,三次握手就是加了几把锁,为了防止各种错误。
HTTP请求报文:请求行,请求头,空行,请求数据
- 请求行:请求方法,请求地址,协议版本
- 请求方法(8种):GET/POST/PUT/HEAD…
- 请求地址:URL(统一资源定位符)<协议>://<主机>:<端口><路径>
http://localhost/index.html?key1=value
协议 主机 路径 参数
HTTP响应报文
- 状态码
- 1xx:提示信息,表示请求已接收,继续处理
- 2xx:成功,表示请求已被成功接收
- 3xx:重定向,要完成请求必须进行更进一步的操作
- 4xx:客户端错误,请求有语法错误,或者请求地址丢失…
- 5xx:服务器端错误
200:响应成功
302:跳转
400:客户端请求有误,语法错误
404:请求资源不存在,可能是地址写错
500:服务器内部错误
TCP四次挥手
AJAX
*PS*:一次ajax请求,并非所有的部分都是异步的,至少readyState==1的onreadystatechange回调以及onloadstart回调是根据文档流顺序同步执行的。ajax步骤
- 创建XMLHttpRequest对象
- 创建HTTP请求,传入需要的各种参数
XMLHttpRequest.open(method,URL,flag,name,password)
- 设置响应HTTP请求状态变化的函数
- 设置获取服务器返回数据的语句
- 发送HTTP请求
xhr.send(data);
- 局部更新
readyState ajax调用过程中的状态
- 0(未初始化):xhr.UNSENT 请求已建立,但未初始化
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
- 1(初始化):xhr.OPENED 请求已建立,单位发送(已经调用open方法,但未调用send方法)
xhr.open(method, url, async);
2(发送数据):xhr.HEADES_RECEIVED 请求已发送(send方法调用,已收到响应头)
if(defaults.method === 'GET') xhr.send(null); else { xhr.setRequestHeader("Content-type", defaults.contentType); xhr.send(data); }
- 3(数据传送中):xhr.LOADING 请求处理中,可能会报错
- 4(完成):xhr.DONE 数据接收完毕,可以通过responseBody responseText获取相应数据
onreadystatechange 在每一个state改变都会被触发(4次),可以在其中绑定事件
xhr.onreadystatechange = function() {
if(xhr.readyState === 4) {
if(xhr.status === 200)
defaults.success.call(xhr, oXhr.responseText);
else {
defaults.error();
}
}
}
跨域问题
- jsonp,
dataType:'jsonp'
,但是需要服务器端返回的是jsonp格式的数据。 - 使用window.name方法,不同标签都能读写window.name内容
- 跨子域,两个子域都将document.domain设置为根域
- websocket,两个域连接同一个服务器,服务器控制两个域的信息通信
- cores,请求头跨域,在需要被返回的页面添加 Access-Control-Allow-rigin
- postMessage
- 服务器代理,将请求发送本域服务器,由服务器获取内容后返回结果
除了服务器代理,1-6都需要服务器可控。我也没有全部了解这些方法,只是列出来,有一天可以参考,当然我希望永远不要用到。XX