Ajax技术
Posted 煜成'Studio
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ajax技术相关的知识,希望对你有一定的参考价值。
Ajax技术(属于前端方面的技术)
即“Asynchronous javascript and XML”,在页面不刷新情况下和服务器进行交互。
特点:异步请求,局部刷新
同步:发送方发出数据后,等接收方发回响应以后才发下一个数据包的通讯方式;
异步:发送方发出数据后,不等接收方发回响应,接着发送下个数据包的通讯方式。
**优点:**Web应用程序更为迅捷地回应用户动作并避免了在网络上发送哪些没有改变的信息,减轻服务器压力。
**缺点:**浏览器实现之间差异,需处理兼容性问题;不利于SEO(SEO只能识别第一次呈现在页面的数据,异步的不行);不能回退和前进;默认不支持跨域访问。
**注意:**ajax技术必须要在网络协议环境下才可以使用,不能把页面直接拖入到浏览器执行,必须在web服务器模式下访问。
AJAX书写步骤:
1.创建AJAX对象;
2.设置请求路径、请求方式等;
3.绑定监听状态改变的处理函数,在处理函数可获取响应数据(回调函数);
4.发送请求;
创建ajax对象时浏览器的兼容性处理
function createAjax()
var ajax;
try //非IE
ajax = new XMLHttpRequest(); //IE浏览器下没有XMLHttpRquest这个对象就会报错
catch(e)
ajax = new ActiveXObject('Microsoft.XMLHTTP');
return ajax;
响应处理和响应流程
响应处理,即对服务响应回浏览器的数据根据状态码和AJAX对象的状态信息进行不同的处理,在绑定状态改变的处理函数中写对应的逻辑代码即可。
AJAX对象有4个属性:
readyState总共有5个状态值,分别为0-4,每个值代表了不同的含义:onreadystatechange,一旦状态发生非标就执行,改变几次,执行几次
0:初始化,AJAX对象还没有完成初始化,new XMLHttpRequest();
1:载入,AJAX对象开始发送请求,ajax.open(请求方式,请求路径);
2:载入完成,AJAX对象的请求发送完成,ajax.send();
3:解析:AJAX对象开始读取服务器的响应,ajax.onreadystatechange;
4:完成,AJAX对象读取服务器响应结束。
status表示响应的HTTP状态码,常见的状态码如下:
200:成功;
302:重定向;
404:找不到资源;
500:服务器错误;
responseText获取字符串形式的响应数据(常用)
responseXML获取XML形式的响应数据
综上,在状态改变的处理函数一般针对ajax.readyState4且ajax.status200的情况才处理(这也是说什么时候可以开始渲染数据?服务器响应完毕且成功获取数据之后),再根据后台返回的数据类型决定从responseText或者responseXML获取服务器响应回来的数据。
ajax的get请求
<script>
let oBtn = document.getElementById("obtn");
let oDiv = document.getElementById("odiv");
oBtn.onclick = () =>
console.log("点击了按钮");
//发送ajax请求
//1.创建ajax对象
let ajax = new XMLHttpRequest();
//2.设置请求方式、请求路径url
ajax.open("GET", "/get_data");
//3.绑定监听状态的改变的处理函数,在这个函数里面可以获取响应数据(回调函数)
ajax.onreadystatechange = () =>
//这个函数里面的代码什么时候执行?状态发生改变的时候就执行
//获取响应的数据
//什么时候页面开始渲染数据?服务器响应完毕之后ajax.readyState为4,并且成功获取数据之后ajax.status为200
if(ajax.readyState === 4 && ajax.status === 200)
//服务器传来的数据用什么表示?ajax.readyState
console.log(ajax.readyState);
//渲染数据到页面上
oDiv.innerhtml = ajax.responseText;
//发送请求
ajax.send();
</script>
服务器代码(nodejs文档中有讲解)
const http = require("http");
const fs = require("fs");
const path = require("path");
const port = 8081;
const server = http.createServer((request, response) =>
//每来一个请求就执行一次这里的代码
//判断浏览器需要哪个资源文件,把下面这些代码进行封装的话就是路由
let reqUrl = request.url;
if(reqUrl === '/' || reqUrl === '/index.html')
//读取页面内容,返回信息
let filePath = path.join(__dirname, "assets", "html", "index.html");
let content = fs.readFileSync(filePath);
response.end(content);
else if(reqUrl === '/detail.html')
//读取页面内容,返回信息
let filePath = path.join(__dirname, "assets", "html", "detail.html");
let content = fs.readFileSync(filePath);
response.end(content); //这句不能放在外面,因为使用let定义的content有块级作用域
else if(reqUrl === '/get_data') //或者正则:/get_data.*/.test(reqUrl)
response.end("接收到ajax的get请求,这是响应给浏览器的数据");
//上面的字符串就是响应到客户端的ajax.responseText
else if(reqUrl.endsWith(".css"))
//如果读取的是一个css文件,也是一个请求,也会执行一次代码
//哪些标签会造成请求?就有href(link)和src(src img)属性的标签,浏览器是自发的请求;还有像按钮、a标签的话需要在表单里而且需要点击过后才会请求
//如果用a标签实现跳转的话,index.html中<a href="/detail.html">跳转到详情页</a>
//这里的跳转地址不是看前端的路径,而是看后端的路由是怎么配的,和这里的if else里的判断内容一致,点击之后也是一次请求
let filePath = path.join(__dirname, "assets", "css", "index.css");
let content = fs.readFileSync(filePath);
response.end(content);
else
response.setHeader("Content-type", "text/html; charset=utf-8"); //不加这句下面的语句会出现乱码
response.end("404错误:该资源找不到!");
)
server.listen(port, (error) =>
console.log(`WebServer is listening at port &port!`);
)
ajax的post请求
附:<input type=“button” value=“提交” />是完全没有提交行为的,而<button></button>在有的浏览器下是有提交行为的
<body>
<from>
用户名:<input type="text" name="username" id="username" /></br>
密&emsp码:<input type="password" name="password" id="password" /></br>
<input type="button" value="提交" id="obtn" />
</from>
<div id="odiv"></div>
<script>
let oBtn = document.getElementById("obtn");
let oDiv = document.getElementById("odiv");
oBtn.onclick = () =>
//post提交
//获取用户填写的数据
let username = document.getElementById("username").value;
let password = document.getElementById("password").value;
let params = //这样的形式是将获取的值看着方便且容易处理,下面处理时还需要转换为服务器需要的JSON格式
username,
password
//Ajax提交(四个步骤)
let ajax = new XMLHttpRequest();
ajax.open("POST", "/login_post");
ajax.onreadystatechange = () =>
if(ajax.readyState === 4 && ajax.status === 200)
//相当于成功后的回调函数,这里可以封装为一个函数,写在最外面,通过调用使用
//ajax.responseText是服务器传过来的字符串
oDiv.innerHTML = ajax.responseText;
ajax.send(JSON.stringify(params)); //服务器需要的是JSON格式的数据,所以需要转换一下
</script>
</body>
服务器代码
const http = require("http");
const fs = require("fs");
const path = require("path");
const port = 8081;
let uname = "laozhuang";
let pwd = "123456";
//包装为函数
function responseEnd(response, dirName, fileName) //dirName文件路径,fileName文件名称
let filePath = path.join(__dirname, "assets", "dirName", "fileName");
let content = fs.readFileSync(filePath);
response.end(content);
const server = http.createServer((request, response) =>
let reqUrl = request.url;
if(reqUrl === '/' || reqUrl === '/index.html')
responseEnd(response, "html", "index.html");
else if(reqUrl === '/detail.html')
responseEnd(response, "html", "detail.html");
else if(reqUrl === '/login.html')
responseEnd(response, "html", "login.html");
else if(reqUrl === '/get_data')
response.end("接收到ajax的get请求,这是响应给浏览器的数据");
else if(reqUrl === '/login_post')
//处理post请求
//一旦post请求过来就会触发data事件
request.on("data", (postData) =>
//postData就是post请求传递过来的参数,是Buffer对象,需要toString()一下
//还需要把JSON格式的字符串转换为对象,因为转为对象才能通过.的方式拿到属性值
//获取到浏览器传过来的数据,就是post请求传递过来的参数
let username, password = JSON.parse(postData.toString()); //解构
//需要查询数据库看有没有用户名,没有的话就需要注册,如果有还需对比密码是否正确,或者其他逻辑操作
if(username === uname && password === pwd)
//还可以跳转之类的操作
response.end("登录成功!");
else
response.end("用户名或者密码错误,登录失败")
)
else if(reqUrl.endsWith(".css"))
responseEnd(response, "css", "index.css");
else if(reqUrl.endsWith(".js"))
responseEnd(response, "js", "index.js");
else
response.setHeader("Content-type", "text/html; charset=utf-8");
response.end("404错误:该资源找不到!");
)
server.listen(port, (error) =>
console.log(`WebServer is listening at port &port!`);
)
避免缓存问题:
AJAX减少了重复数据的载入从而提高页面载入速度,是因为数据会一直缓存在内存中,当提交的URL和历史URL一致时,就不需要提交给服务器。虽然降低了服务器的负载提高了用户体验,但是不能获取到最新的数据,为了保证数据都是最新的,就需要禁止其缓存功能,主要以下几种方式:
1.在URL后面加一个随机数:Math.random()
//客户端代码
ajax.open("GET", "/get_data" + Math.random());
//服务端代码
else if(reqUrl.startsWith('/get_data'))
response.end("接收到ajax的get请求,这是响应给浏览器的数据");
//上面的字符串就是响应到客户端的ajax.responseText
2.在URL后面加上时间戳:new Date().getTime(),从1970.01.01开始的毫秒数
3.在使用AJAX发送请求前加上ajax.setRequestHeader(“Cache-Control”, “no-cache”);
ajax.open(...);
ajax.setRequestHeader('Cache-Control', 'no-cache'); //请求头设置,在ajax.open()后面
ajax.send();
4.手动将开发者工具下的Network的Disable cache勾上
超时处理:
有时网络会出现问题或者服务端出问题导致请求时间过长,一般提示网络请求稍后重试,以增加用户的体验感。代码中可以通过定时器和请求中断来实现超时处理的效果。
var timer = setTimeout(() =>
//取消请求,终端请求
ajax.abort();
alert("请稍后重试")
, time)
方法抽取(不是最终形式,工作中也不会这样写,了解)
一个ajax请求,请求方式、请求路径、请求参数、获得服务端内容后的回调函数,时间等可以封装为函数,这样get和post请求就可以写在一起了
function ajax(method, url, param, success, time)
var ajax;
//处理ajax获取时候的兼容性问题
try //非IE
ajax = new XMLHttpRequest();
catch(e) //IE
ajax = new ActiveXObject('Microsoft.XMLHTTP');
if(method === 'get')
param = encodeURL(param); //针对get请求的查询参数出现中文的编码处理
url = url + '?' + param;
param = null;
ajax.open(method, url);
if(method === 'post')
//请求体格式,例如name=nodejs&age=11
ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
//也可以在<form>标签中设设置
//<form enctype="application/x-www-form-urlencoded">...</form>
ajax.onreadystatechange = function()
if(ajax.readyState === 4 && ajax.status === 200)
success(ajax.responseText); //在外面设置的获取服务端数据后处理数据的回调函数
ajax.send(param);
var time = setTimeout(() =>
ajax.abort();
, time)
jQuery的ajax方法、get请求、post请求(视频没看), 就 是 指 的 j Q u e r y , 就是指的jQuery, 就是指的jQuery,.ajax就是jQuery.ajax
以上是关于Ajax技术的主要内容,如果未能解决你的问题,请参考以下文章