http协议和原生xhr
三次握手
- 客户端通过随机端口与服务端某个固定端口(一般为80)建立连接 三次握手
- 客户端向服务器发送一个连接请求
- 服务器向客户端返回一个确认信息
- 客户端将连接请求及这个确认信息发送服务器
- 客户端通过这个连接发送请求到服务端(这里的请求是名词)
- 服务端监听端口得到的客户端发送过来的请求
- 服务端通过连接响应给客户端状态和内容
状态代码由三位数字组成,第一个数字定义了响应的类别,且有五种可能取值。
- 1xx:指示信息 —— 表示请求已接收,继续处理。
- 2xx:成功 —— 表示请求已被成功接收、理解、接受。
- 3xx:重定向 —— 要完成请求必须进行更进一步的操作。
- 4xx:客户端错误 —— 请求有语法错误或请求无法实现。
- 5xx:服务器端错误 —— 服务器未能实现合法的请求。
API 详解
xhr.open() 发起请求,可以是get、post方式
xhr.setRequestHeader() 设置请求头
xhr.send() 发送请求主体get方式使用xhr.send(null)
xhr.onreadystatechange = function () {} 监听响应状态
readstate 属性有五个状态:
- xhr.readyState = 0时,(未初始化)还没有调用send()方法
- xhr.readyState = 1时,(载入)已调用send()方法,正在发送请求
- xhr.readyState = 2时,(载入完成)send()方法执行完成,已经接收到全部响应内容
- xhr.readyState = 3时,(交互)正在解析响应内容
- xhr.readyState = 4时,(完成)响应内容解析完成,可以在客户端调用了
xhr.status表示响应码,如200
xhr.statusText表示响应信息,如OK
xhr.getAllResponseHeaders() 获取全部响应头信息
xhr.getResponseHeader(‘key’) 获取指定头信息
xhr.responseText、xhr.responseXML都表示响应主体
ajax的代码一定基于http协议,因为ajax的作用就是实现请求的发送和响应的接收,它相当于代替之前的浏览器的相关的操作
模拟jquery封装Ajax
// 为了避免全局污染,可以将成员封装到对象中
// $就是我当前的对象的名称,在js中,支持使用$做为变量名
// 使用const原因只有一个,我这个$工具以后只希望别人使用,而不希望别人修改
const $ = {
// options.type:请求方式
// options.url:请求url
// options.data:请求所需要传递的参数
// options.success:数据请求成功之后的处理逻辑--回调函数
// option.dataType:响应数据的目标类型,用户希望你给他"返回"什么类型的数据
ajax:function(options){
// 处理参数,为参数设置默认值(如果你传递了参数,就使用你传递的参数,如果没有传递参数,就给你默认值)
// 如果访问对象的不存在的属性,返回undefined
let type = options.type || 'get'
let url = options.url
let data = options.data || ''
let success = options.success
let dataType = options.dataType || "text/html"
// 创建异步对象
let xhr = new XMLHttpRequest()
// 发送请求
// 请求行
if(type == 'get'){
// 拼接参数 http://127.0.0.1:3002/getuserbyid?id=1
url = url + "?" + data
// 拼接之后,将data参数重置为null
data = null
}
xhr.open(type,url)
// 请求头
if(type == 'post'){
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded')
}
// 请求体
xhr.send(data)
// 接收响应
xhr.onload = function(){
// 我也不知道你要做什么,我只是一个工具函数,那么你得告诉我你想做什么
// 调用回调函数,同时传入获取到的数据
// &&判断success是否传递了,如果传递了则调用,否则不调用
// 转换
let res = null
//数据有可能是HTML,CSS,JS,JSON数据。。。。。
if(dataType == 'json'){ // 说明你想要js对象
res = JSON.parse(xhr.response)
}else if(dataType == 'xml'){ // 说明你要xml格式的数据
res = xhr.responseXML
}else { // 默认值
res = xhr.response
}
// let res = xhr.response
success && success(res)
}
}
}
jq中还有一些其他属性
- beforeSend:function () {} :请求发起前调用
- timeout :请求超时
- error :错误响应时调用
- complete :响应完成时调用(包括成功和失败)