AJAX简介
AJAX全称为Asynchronous JavaScript And XML,就是异步的JS和XML,通过AJAX可以在浏览器中向服务器发送异步请求。
XML简介
XML(Extensible Markup Language)可扩展标记语言。XML被设计用来传输和存储数据。XML和HTML类似,不同的是HTML中都是预定义标签,而XML中没有预定义标签,全都是用来表示一些数据。
XMLHTTPRequest对象
XMLHTTPRequest对象,顾名思义:是基于XML的HTTP请求。XMLHTTPRequest是一个浏览器接口,使得JavaScript可以进行HTTP(S)通信。自从浏览器提供有了XMLHTTPRequest这个接口之后,AJAX操作就此诞生。XMLHTTP是AJAX网页开发技术的重要组成部分。除XML之外,XMLHTTP还能用于获取其它格式的数据,如JSON或者甚至纯文本。
XHR的5种状态
XHR有5种状态,值分别是0,1,2,3,4
0:实例出来的那一刻就是0,初始状态。
1:open已经调用,但是send还没有调用,此时可以修改请求头的内容。
2:send已经调用,已经无法修改请求头
3:已经回来一部分数据,小的数据会在此阶段一次性接收完毕,较大的数据有待进一步接收,响应头回来了
4:数据全部接收完毕
xhr.onreadystatechange = ()=>{
/* if(xhr.readyState === 1){
xhr.setRequestHeader('name','lai')//设置响应头
} */
/* if(xhr.readyState === 2){
xhr.setRequestHeader('name','lai')//报错
} */
/* if(xhr.readyState === 3){
console.log(xhr.response)
console.log(xhr.getAllResponseHeaders())//获取所有响应头
console.log(xhr.getResponseHeader('content-length'))
} */
if(xhr.readyState === 4 && (xhr.status >= 200 && xhr.status <= 300)){
// console.log(xhr.response)
document.getElementsByClassName('content')[0].innerText = xhr.response
}
ajax-----get请求
//1.创建xhr实例对象
const xhr = new XMLHttpRequest()
//2.监听状态
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4 && (xhr.status >= 200 && xhr.status <= 300)){
document.getElementsByClassName('content')[0].innerText = xhr.response
}
}
//3.指定发送请求的:method、url、参数
// xhr.open('GET','http://localhost:8080/test_get?name=赖&age=22') //携带query参数
xhr.open('GET','http://localhost:8080/test_get2/赖/22') //携带params参数
//4.发送请求
xhr.send()
get请求可以携带两种参数,分别是query参数(也叫urlencoded编码格式,形如key:value这种形式)和params参数,params参数需要服务器端用占位符接收
服务器端代码:
//响应get请求-----接收query参数
app.get('/test_get',(request,response)=>{
response.send('hello_test_get!!')
console.log('有人发送了带query参数的get请求:',request.query)
})
//响应get请求-----接收params参数
app.get('/test_get2/:name/:age',(request,response)=>{
response.send('hello_test_get2!!')
console.log('有人发送了带params参数的get2请求:',request.params)
})
ajax----post请求
//1.创建xhr实例对象
const xhr = new XMLHttpRequest()
//2.监听状态
xhr.onreadystatechange = () =>{
if(xhr.readyState === 4 && (xhr.status >= 200 && xhr.status <= 300)){
document.getElementsByClassName('content')[0].innerText = xhr.response
}
}
//3.指定发送请求的:method、url、参数
xhr.open('POST','http://localhost:8080/test_post')
//追加响应头用于标识携带请求体参数的编码格式---urlencoded
// xhr.setRequestHeader('Content-type','application/x-www-form-urlencoded')
//追加响应头用于标识携带请求体参数的编码格式---json
xhr.setRequestHeader('Content-type','application/json')
const person = {name:'赖',age:22}
//4.发送请求
// xhr.send('name=赖&age=22') //携带urlencoded编码形式的请求体参数
xhr.send(JSON.stringify(person)) //携带json编码形式的请求体参数
post请求可以携带3种参数,query参数,params参数,body(请求体)参数,一般使用请求体参数,请求体参数需要写在xhr.send()里,同时需要追加响应头用于标识请求体参数的编码格式,如xhr.setRequestHeader(‘Content-type’,‘application/x-www-form-urlencoded’)设置请求体参数为urlencoded编码形式, xhr.setRequestHeader(‘Content-type’,‘application/json’)设置请求体参数为json编码形式
//responseType用于指定返回数据的格式
xhr.responseType = 'json'
ajax-----请求异常和超时处理
//创建xhr实例
const xhr = new XMLHttpRequest()
//绑定监听
xhr.onreadystatechange = () =>{
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
console.log(xhr.response)
}
}
}
//配置请求
xhr.open('GET','http://localhost:8080/getPerson_Delay')
//配置出错的回调
xhr.onerror = () => {
alert('网络连接出错,请检查网络连接')
}
xhr.timeout = 2000 //单位为毫秒
//超时的回调
xhr.ontimeout = () => {
alert('网络请求超时,请检查网络')
}
//指定返回参数格式
xhr.responseType = 'json'
//发送请求
xhr.send()
xhr里几个处理异常和超时的API:xhr.onerror(配置出错的回调)、xhr.timeout(配置超时的时间)、xhr.ontimeout(超时的回调)
ajax----取消请求
btn1.onclick = () => {
xhr.abort()
}
使用abort()来取消请求
ajax-----避免多次重复请求
let xhr
let loadState
//绑定点击事件
btn.onclick = () => {
if(loadState) xhr.abort()
//创建xhr实例
xhr = new XMLHttpRequest()
//绑定监听
xhr.onreadystatechange = () =>{
if(xhr.readyState === 4){
if(xhr.status >= 200 && xhr.status < 300){
console.log(xhr.response)
loadState = false
}
}
}
//配置请求
xhr.open('GET','http://localhost:8080/getPerson_Delay')
//指定返回参数格式
xhr.responseType = 'json'
//发送请求
xhr.send()
loadState = true
}
通过添加一个loadState来判断数据是否已经返回,从而用abort()来取消之前发送的请求
jQuery封装的ajax
ajax-get请求(完整版)
$.ajax({
url:'http://localhost:8080/jQuery_getPerson', //配置请求地址
method:'GET',//配置请求方式,默认是get
data:{school:'ycu'},//携带的数据
dataType:'json',//返回数据的格式
timeout:2000,//超时时间
//成功的回调
success:(result,responseText,xhr) => {
console.log('成功了')
div.append(`<div>${result.name}</div>`)
},
//失败的回调
error:(xhr) => {
console.log('请求出错了')
}
})
ajax-get请求(精简版)
$.get('http://localhost:8080/jQuery_getPerson',{school:'ycu'},(result) => {
console.log(result)
},'JSON')
ajax-post请求(完整版)
$.ajax({
url:'http://localhost:8080/jQuery_getPerson', //配置请求地址
method:'POST',//配置请求方式,默认是get
data:{school:'ycu'},//携带的数据
dataType:'json',//放回数据的格式
timeout:2000,//超时时间
//成功的回调
success:(result,responseText,xhr) => {
console.log('成功了')
div.append(`<div>${result.name}</div>`)
},
//失败的回调
error:(xhr) => {
console.log('请求出错了')
}
})
ajax-post请求(精简版)
$.post('http://localhost:8080/jQuery_postPerson',{school:'ycu'},(result) => {
console.log(result)
},'JSON')
为什么会有跨域这个问题
原因是浏览器为了安全,而采用的同源策略(Same origin policy)
什么是同源策略?
1.同源策略是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript的浏览器都会支持这个策略
2.web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现
3.所谓同源是指:协议,域名(IP),端口必须完全相同
非同源受到哪些限制?
1、Cookie不能获取;`
2、DOM无法获取`
3、Ajax请求不能获取数据
如何在开发中解决跨域问题:
1.JSONP
①JSONP是什么
JSONP(JSONP with Padding),是一个非官方的跨域解决方案,jsonp不是一种技术,而是程序员的“智慧结晶"(利用了标签请求资源不受同源策略限制的特点),只支持get请求,需要前后端人员相互配合
②JSONP解决跨域问题
//1.创建script节点
const scriptNode = document.createElement('script')
//2.给script设置src属性
scriptNode.src = 'http://localhost:8080/test_jsonp?callback=demo'
//3.将script放入页面
document.body.appendChild(scriptNode)
//4.准备一个函数
window.demo = (a) => {
console.log(a)
}
//5.移除使用过的script节点
document.body.removeChild(scriptNode)
服务端代码
//响应使用jsonp发送的请求
app.get('/test_jsonp',(request,response)=>{
const {callback} = request.query
const person = {name:'赖',age:22}
response.send(`${callback}(${JSON.stringify(person)})`)
console.log('有人发送了使用jsonp发送的请求:')
})
③jQuery封装的JSONP
$('#btn').click(() => {
$.getJSON('http://localhost:8080/test_jsonp?callback=?',{},(data) => {
console.log(data)
})
})
2.CORS(后端技术)
①CORS是什么
CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持所有常见的请求。
②CORS怎么工作
CORS是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行
③CORS解决跨域问题
//1.创建xhr实例对象
const xhr = new XMLHttpRequest()
//2.监听状态
xhr.onreadystatechange = ()=>{
if(xhr.readyState === 4 && (xhr.status >= 200 && xhr.status <= 300)){
console.log(xhr.response)
console.log(xhr.getAllResponseHeaders())
}
}
//3.指定发送请求的:method、url、参数
xhr.open('PUT','http://localhost:8080/test_put')
//4.发送请求
xhr.send()
//响应options请求
app.options('/test_put',(request,response) => {
response.setHeader('Access-Control-Allow-Origin','*')
response.setHeader('Access-Control-Expose-Headers','*') //暴露请求头
response.setHeader('Access-Control-Allow-Methods','*') //允许哪些方法
response.send('hello_test_options')
})
//响应put请求
app.put('/test_put',(request,response) => {
response.setHeader('Access-Control-Allow-Origin','*')
response.setHeader('Access-Control-Expose-Headers','*') //暴露请求头
response.send('hello_test_put')
})
get、put请求是简单请求,put、delete请求是复杂请求,会发起两次请求,第一次叫预请求(嗅探请求),所以解决put请求的跨域问题需要再配置一个options
使用中间件解决跨域,安装cors
npm i cors
const cors = require('cors')
app.use(cors())