好程序员web前端训练共享JavaScript学习笔记ajax及ajax封装,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()
}
}
}}
发表评论