简介
- AJAX 全称为 Asynchronous JavaScript And XML,就是异步的 JS 和 XML(现在已经基本被json取代)。
- 通过 AJAX 可以在浏览器中向服务器发送异步请求,最大的优势:无刷新获取数据。
- AJAX 不是新的编程语言,而是一种将现有的标准组合在一起使用的新方式。
优点
- 无需刷新页面即可与服务器进行通信。
- 允许根据用户事件来更新部分页面内容。
缺点
- 没有浏览历史,不能回退
- 存在跨域问题,ajax默认是遵循同源策略,跨域请求是无法通过ajax请求的
- seo不友好,无法通过爬虫获取到ajax请求的数据,也无法在浏览器的源代码选项中获取到相关的源码
总而言之:ajax不是什么新鲜的对象,我们把它当作是在一个已有的网页中,我们可以通过它请求后端的数据来显示在之前的网页中。
AJAX的使用
- GET请求
btn.onclick=function(){//1. 创建对象const xhr =newXMLHttpRequest();//浏览器开发者选项中的xhr里面的信息就是该页面的ajax请求//2. 初始化 设置请求方法和 url
xhr.open('GET','http://127.0.0.1:8000/server?a=100&b=200&c=300');//3. 发送
xhr.send();//4. 事件绑定 处理服务端返回的结果
xhr.onreadystatechange=function(){//判断 (服务端返回了所有的结果)if(xhr.readyState ===4){// 2xx 成功if(xhr.status >=200&& xhr.status <300){//响应 // console.log(xhr.status);//状态码// console.log(xhr.statusText);//状态字符串// console.log(xhr.getAllResponseHeaders());//所有响应头// console.log(xhr.response);//响应体//设置 result 的文本
result.innerHTML = xhr.response;}else{}}}}
- POST请求
result.addEventListener("mouseover",function(){//1. 创建对象const xhr =newXMLHttpRequest();
xhr.responseType='json'//2. 初始化 设置类型与 URL
xhr.open('POST','http://127.0.0.1:8000/server');//有时候ie浏览器会有缓存问题,因此通常情况下最好给每个url拼接上一个时间戳参数//设置请求头
xhr.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
xhr.setRequestHeader('name','xxx');//自定义的请求头需要在后端中设置Access-Control-Allow-Headers响应头//3. 发送
xhr.send('a=100&b=200&c=300');// xhr.send('a:100&b:200&c:300');// xhr.send('1233211234567');//4. 事件绑定
xhr.onreadystatechange=function(){//判断if(xhr.readyState ===4){if(xhr.status >=200&& xhr.status <300){//处理服务端返回的结果
result.innerHTML = xhr.response;}}}});
- 超时与网络异常问题
btn.addEventListener('click',function(){const xhr =newXMLHttpRequest();//超时设置 2s 设置
xhr.timeout =2000;//超时回调
xhr.ontimeout=function(){alert("网络异常, 请稍后重试!!");}//网络异常回调
xhr.onerror=function(){alert("你的网络似乎出了一些问题!");}
xhr.open("GET",'http://127.0.0.1:8000/delay');
xhr.send();
xhr.onreadystatechange=function(){if(xhr.readyState ===4){if(xhr.status >=200&& xhr.status<300){
result.innerHTML = xhr.response;}}}})
- 重复请求问题——关键在于设置一个标志位
<script>//获取元素对象const btns = document.querySelectorAll('button');let x =null;//标识变量let isSending =false;// 是否正在发送AJAX请求
btns[0].onclick=function(){//判断标识变量if(isSending) x.abort();// 如果正在发送, 则取消该请求, 创建一个新的请求
x =newXMLHttpRequest();//修改 标识变量的值
isSending =true;
x.open("GET",'http://127.0.0.1:8000/delay');
x.send();
x.onreadystatechange=function(){if(x.readyState ===4){//修改标识变量
isSending =false;}}}// abort
btns[1].onclick=function(){
x.abort();}</script>
- 使用express框架搭建一个后端
//1. 引入expressconst express =require('express');//2. 创建应用对象const app =express();//3. 创建路由规则// request 是对请求报文的封装// response 是对响应报文的封装//all方法表示所有类型的请求都可以,get、post、delete。。。
app.all('/server',(request, response)=>{//设置响应//response.set("Access-Control-Allow-Origin","http://127.0.0.1:3000");//只对http://127.0.0.1:3000这个url的请求允许跨域
response.setHeader("Access-Control-Allow-Origin","*")//对所有请求允许跨域
response.setHeader("Access-Control-Allow-Headers","*")//允许各种请求头,包括自定义的和http已经定义的请求头
response.send('HELLO EXPRESS');});//4. 监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动, 8000 端口监听中....");});
AJAX的请求状态
xhr.readyState 可以用来查看请求当前的状态
- 0: 表示 XMLHttpRequest 实例已经生成,但是 open()方法还没有被调用。
- 1: 表示 send()方法还没有被调用,仍然可以使用 setRequestHeader(),设定 HTTP请求的头信息。
- 2: 表示send()方法已经执行,并且头信息和状态码已经收到。
- 3: 表示正在接收服务器传来的body部分的数据。
- 4: 表示服务器数据已经完全接收,或者本次接收已经失败了
跨域问题
- 同源策略 同源策略是浏览器的一种安全策略。所谓的同源是指:协议、域名】端口号必须完全相同,而违背同源策略就是跨域。 如果违背同源策略,浏览器的开发者工具就会报如下错误,该网页是从5500端口获取的,但是ajax的请求却是8000端口。 解决跨域问题有两种方式:
- CORS1. CORS(Cross-Origin Resource Sharing),跨域资源共享。CORS 是官方的跨域解决方案,它的特点是不需要在客户端做任何特殊的操作,完全在服务器中进行处理,支持get 和 post 请求。跨域资源共享标准新增了一组 HTTP 首部字段,允许服务器声明哪些源站通过浏览器有权限访问哪些资源2. CORS 怎么工作的? CORS 是通过设置一个响应头来告诉浏览器,该请求允许跨域,浏览器收到该响应以后就会对响应放行。
- JSONP JSONP(JSON with Padding),是一个非官方的跨域解决方案,只支持 get 请求。在网页有一些标签天生具有跨域能力,比如:img link iframe script。JSONP 就是利用 script 标签的跨域能力来发送请求的。案例如下:
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>案例</title></head><body>用户名:<input type="text" id="username"><p></p><script>//获取 input 元素const input = document.querySelector('input');const p = document.querySelector('p');//声明 handle 函数functionhandle(data){
input.style.border ="solid 1px #f00";//修改 p 标签的提示文本
console.log(data)
p.innerHTML = data.name;}//绑定事件
input.onblur=function(){//获取用户的输入值let username =this.value;//向服务器端发送请求 检测用户名是否存在//1. 创建 script 标签const script = document.createElement('script');//2. 设置标签的 src 属性
script.src ='http://127.0.0.1:8000/server';//3. 将 script 插入到文档中
document.body.appendChild(script);}</script></body></html>
//1. 引入expressconst express =require('express');//2. 创建应用对象const app =express();//3. 创建路由规则// request 是对请求报文的封装// response 是对响应报文的封装
app.all('/server',(request, response)=>{//设置响应// response.setHeader("Access-Control-Allow-Origin","*")// response.setHeader("Access-Control-Allow-Headers","*")const data ={name:'sdsdsd'};
response.end(`handle(${JSON.stringify(data)})`);//这样就会回调到html中的handle方法});//4. 监听端口启动服务
app.listen(8000,()=>{
console.log("服务已经启动, 8000 端口监听中....");});
最后
除了前面介绍的几个字ajax的请求之外,fetch函数也是可以用来进行ajax请求的
https://developer.mozilla.org/zh-CN/docs/Web/API/fetch
版权归原作者 hzulwy 所有, 如有侵权,请联系我们删除。