好程序员web前端训练共享JavaScript学习笔记ajax及ajax封装

  好程序员web前端训练共享JavaScript学习笔记ajaxajax封装,ajax 全名 async javascript and XML
  是前后台交互的才能
  也便是咱们客户端给服务端发送音讯的东西,以及承受呼应的东西
  是一个 默许异步 履行机制的功用
  AJAX 的优势
.  不需求插件的支撑,原生 js 就能够运用
.  用户体会好(不需求改写页面就能够更新数据)
.  减轻服务端和带宽的担负
.  缺陷: 查找引擎的支撑度不行,由于数据都不在页面上,查找引擎查找不到
  AJAX 的运用
  在 js 中有内置的结构函数来创立 ajax 目标
  创立 ajax 目标今后,咱们就运用 ajax 目标的办法去发送恳求和承受呼应
创立一个 ajax 目标
// IE9及以上const xhr = new XMLHttpRequest()​// IE9以下const xhr = new ActiveXObject('Mricosoft.XMLHTTP')
上面便是有了一个 ajax 目标
咱们就能够运用这个 xhr 目标来发送 ajax 恳求了
装备链接信息
const xhr = new XMLHttpRequest()​// xhr 目标中的 open 办法是来装备恳求信息的// 第一个参数是本次恳求的恳求办法 get / post / put / ...// 第二个参数是本次恳求的 url // 第三个参数是本次恳求是否异步,默许 true 表明异步,false 表明同步// xhr.open('恳求办法', '恳求地址', 是否异步)xhr.open('get', './data.php')
上面的代码履行结束今后,本次恳求的根本装备信息就写完了
发送恳求
const xhr = new XMLHttpRequest()xhr.open('get', './data.php')​// 运用 xhr 目标中的 send 办法来发送恳求xhr.send()
上面代码是把装备好信息的 ajax 目标发送到服务端
一个根本的 ajax 恳求
一个最根本的 ajax 恳求便是上面三步
可是光有上面的三个过程,咱们的确能把恳求发送的到服务端
假如服务端正常的话,呼应也能回到客户端
可是咱们拿不到呼应
假如想拿到呼应,咱们有两个前提条件
.本次 HTTP 恳求是成功的,也便是咱们之前说的 http 状况码为 200 ~ 299
.ajax 目标也有自己的状况码,用来表明本次 ajax 恳求中各个阶段
ajax 状况码
ajax 状况码 - xhr.readyState
是用来表明一个 ajax 恳求的悉数过程中的某一个状况
readyState === 0: 表明未初始化完结,也便是 open 办法还没有履行
readyState === 1: 表明装备信息现已完结,也便是履行完 open 之后
readyState === 2: 表明 send 办法现已履行完结
readyState === 3: 表明正在解析呼应内容
readyState === 4: 表明呼应内容现已解析结束,能够在客户端运用了

这个时分咱们就会发现,当一个 ajax 恳求的悉数过程中,只有当 readyState === 4 的时分,咱们才能够正常运用服务端给咱们的数据
所以,合作 http 状况码为 200 ~ 299 
一个 ajax 目标中有一个成员叫做 xhr.status
这个成员便是记载本次恳求的 http 状况码的

两个条件都满意的时分,才是本次恳求正常完结
readyStateChange
在 ajax 目标中有一个事情,叫做 readyStateChange 事情
这个事情是专门用来监听 ajax 目标的 readyState 值改动的的行为
也便是说只需 readyState 的值发生变化了,那么就会触发该事情
所以咱们就在这个事情中来监听 ajax 的 readyState 是不是到 4 了
const xhr = new XMLHttpRequest()xhr.open('get', './data.php')​xhr.send()​xhr.onreadyStateChange = function () {
// 每次 readyState 改动的时分都会触发该事情 // 咱们就在这儿判别 readyState 的值是不是到 4 // 而且 http 的状况码是不是 200 ~ 299 if (xhr.readyState === 4 && /^2d{2|$/.test(xhr.status)) {
// 这儿表明验证经过 // 咱们就能够获取服务端给咱们呼应的内容了 }}
responseText
ajax 目标中的 responseText 成员
便是用来记载服务端给咱们的呼应体内容的
所以咱们就用这个成员来获取呼应体内容就能够
const xhr = new XMLHttpRequest()xhr.open('get', './data.php')​xhr.send()​xhr.onreadyStateChange = function () {
if (xhr.readyState === 4 && /^2d{2|$/.test(xhr.status)) {
// 咱们在这儿直接打印 xhr.responseText 来检查服务端给咱们回来的内容 console.log(xhr.responseText)
}}
运用 ajax 发送恳求时带着参数
咱们运用 ajax 发送恳求也是能够带着参数的
参数便是和后台交互的时分给他的一些信息
可是带着参数 get 和 post 两个办法仍是有差异的
发送一个带有参数的 get 恳求
get 恳求的参数就直接在 url 后边进行拼接就能够
const xhr = new XMLHttpRequest()// 直接在地址后边加一个 ?,然后以 key=value 的方法传递// 两个数据之间以 & 切割xhr.open('get', './data.php?a=100&b=200')​xhr.send()
这样服务端就能承遭到两个参数
一个是 a,值是 100
一个是 b,值是 200
发送一个带有参数的 post 恳求
post 恳求的参数是带着在恳求体中的,所以不需求再 url 后边拼接
const xhr = new XMLHttpRequest()xhr.open('post', './data.php')​// 假如是用 ajax 目标发送 post 恳求,必需求先设置一下恳求头中的 content-type// 告知一下服务端我给你的是一个什么姿态的数据格局xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')​// 恳求体直接再 send 的时分写在 () 里边就行// 不需求问号,直接便是 'key=value&key=value' 的方法xhr.send('a=100&b=200')
application/x-www-form-urlencoded 表明的数据格局便是 key=value&key=value
同源战略
同源战略是由浏览器给的
浏览器不允许咱们向他人发送恳求,只能向自己的服务器发送恳求
当咱们想向他人的服务器发送恳求的时分,就会被浏览器阻挠了
什么是 “他人的服务器” 呢?
当 恳求协议/域名/端口号 有恣意一个不同的时分,那么就算是他人的服务器
这个时分就会触发同源战略

咱们管触发了 同源战略 的恳求叫做跨域恳求
完成一个跨域恳求
有的时分咱们是需求完成跨域恳求的
咱们需求多个服务器给一个页面供给数据
那么这个时分咱们就要想办法处理跨域问题
JSONP
jsonp 是咱们完成跨域恳求的手法,是把咱们之前的东西组合在一起运用的技术手法罢了
运用的是 script 标签来完成
script 标签的实质
浏览器给咱们供给了一个 script 标签
它的实质便是恳求一个外部资源,是不遭到同源战略的影响的
一起 script 标签的 src 特点,也是一种恳求,也能被服务器接收到
而且:
script标签的src特点恳求回来的东西是一个字符串,浏览器会把这个字符串当作 js 代码来履行

所以咱们就能够运用这个 script 标签的 src 特点来进行跨域恳求了
装备署理(了解)
署理,分红两种,正向署理和反向署理
正向署理
有一个客户端需求向一个非同源的服务器B发送恳求
咱们建立一个和客户端同源的服务器A
当客户端发送恳求的时分,由服务器A来承受
再由服务器A向服务器B发送恳求,由于 同源战略是由浏览器给的,服务器之间没有
服务器B承遭到恳求今后,会处理恳求,并把呼应回来给服务器A
再由服务器A把呼应给到客户端就能够了
咱们就能够用这个办法来进行跨域恳求了
反向署理
反向署理一般是用来做负载均衡的
当我恳求一个服务器的时分,其实恳求的是服务器端设置的署理服务器
由署理服务器把若干许多的恳求分发给不同的服务器进行处理
再由服务器把呼应给到署理服务器
署理服务器回来给客户端
封装 AJAX
ajax 运用起来太费事,由于每次都要写许多的代码
那么咱们就封装一个 ajax 办法来让咱们运用起来简略一些
确认一下运用的办法
由于有一些内容能够不传递,咱们能够运用默许值,所以选择目标传递参数的办法
// 运用的时分直接调用,传递一个目标就能够
ajax({
url: '', // 恳求的地址
type: '', // 恳求办法
async: '', // 是否异步
data: '', // 带着的参数
dataType: '', // 要不要履行 json.parse
success: function () {} // 成功今后履行的函数
})
确认好运用办法今后,就开端书写封装函数
封装
function ajax(options) {
// 先预备一个默许值 var defInfo = {

url: '', // 地址不需求默许值    type: 'GET', // 恳求办法的默许值是 GET    async: false, // 默许值是异步    data: '', // 参数没有默许值    dataType: 'string', // 默许不需求履行 json.parse    success () {}, // 默许是一个函数  }​

// 先来判别一下有没有传递 url,假如没有,直接抛出反常 if (!options.url) {

throw new Error('url 有必要传递')

}​
// 有了 url 今后就,咱们就把用户传递的参数和咱们的默许数据兼并 for (let key in options) {

defInfo[key] = options[key]

}​
// 接下来的悉数咱们都是运用咱们的 defInfo 就能够了 // 第一步便是判别参数 data // data 能够不传递,能够为空 // data 也能够是一个 key=value&key=value 格局的字符串 // data 也能够是一个目标 // 不然就抛出反常 if (!(typeof defInfo.data === 'string' && /^(w+=w+&?)*$/.test(defInfo.data) || Object.prototype.toString.call(defInfo.data) === '[object Object]')) {

throw new Error('请依照要求传递参数')

}​
// 参数处理结束今后,在判别 async 的数据类型 // 只能传递 布尔数据类型 if (typeof defInfo.async !== 'boolean') {

throw new Error('async 参数只承受布尔数据类型')

}​
// 在接下来就判别 type // 恳求办法咱们只承受 GET 或着 POST if (!(defInfo.type.toUpperCase() === 'GET' || defInfo.type.toUpperCase() === 'POST')) {

throw new Error('现在本插件只承受 GET 和 POST 办法,请等待更新')

}​
// 接下来便是判别 success 的判别,有必要是一个函数 if (Object.prototype.toString.call(defInfo.success) !== '[object Function]') {

throw new Error('success 只承受函数数据类型')

}​
// 参数都没有问题了 // 咱们就要把 data 处理一下了 // 由于 data 有可能是目标,当 data 是一个目标的时分,咱们要把它转换成一个字符串 var str = ''
if (Object.prototype.toString.call(defInfo.data) === '[object Object]') {

for (let attr in defInfo.data) {
str += `${attr}=${defInfo.data[attr]}&`
}
str = str.slice(0, -1)
defInfo.data = str

}​
// 参数悉数验证过了今后,咱们就能够开端进行正常的 ajax 恳求了 // 1. 预备一个 ajax 目标 // 由于要处理兼容问题,所以咱们预备一个函数 function createXHR() {

if (XMLHttpRequest) {
return new XMLHttpRequest()
} else {
return new ActiveXObject('Microsoft.XMLHTTP')
}

}​
// 2. 创立一个 ajax 目标 var xhr = createXHR()​
// 3. 进行 open xhr.open(defInfo.type, defInfo.url + (defInfo.type.toUpperCase() === 'GET' ? ?${defInfo.data}&_=${new Date().getTime()} : ''), defInfo.async)​
if (defInfo.type.toUpperCase() === 'POST') {

xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded')

}​
// 4. 进行 send xhr.send((defInfo.type.toUpperCase() === 'POST' ? ${defInfo.data} : ''))​
// 5. 承受呼应 xhr.onreadystatechange = function () {

if (xhr.readyState === 4 && /2d{2}/.test(xhr.status)) {
// 表明成功,咱们就要履行 success      // 可是要进行 dataType 的判别      if (defInfo.dataType === 'json') {
defInfo.success(JSON.parse(xhr.responseText))
} else {
defInfo.success()
}
}

}}