一、什么是ajax?
ajax即 Asynchronous [e’sɪŋkrənəs] Javascript And XML, AJAX 不是一门的新的语言,而是对现有技术的综合利用。 本质是在HTTP协议的基础上以异步的方式与服务器进行通信。
二、什么是同步什么是异步?
同步: 指的就是事情要一件一件做。等做完前一件才能做后一件任务,有点像走独木桥,必须排着队一个一个来。
异步:不受当前任务的影响,多个事情同时进行,做一件事情时,不影响另一件事情的进行。简单的可以理解为道路加宽,单车道变成了多车道。编程中,异步程序代码执行时不会阻塞其它程序代码执行,从而提升整体执行效率。
三、异步应用实际操作的场景
听完基本概念,或许还有点懵。异步在我们平常编程的时候的应用场景基本分为以下三点:
1.实现无页面跳转刷新的表单验证。
当然这里说的不是仅仅前端对字符串的校验。异步验证,验证的不是客户输入的字符串是否符合标准,而是验证客户想要注册的用户名是否已经存在。这一操作是我们是需要访问服务器的,并且还需要查询数据库的。比如百度账户的注册页面百度注册页面
2.百度搜索提示,及相关内容的展示
一般我们在百度是搜查东西的时候,都会先输入我们的搜索关键字然后点击按钮。然而现在能实现边输入内容边显示相关信息,大大提升了用户的满意度。但这不仅仅是改变监听事件这么简单,更需要ajax异步请求来实现。
3.新浪微博评论(异步加载)
新浪微博我们大家都有玩过,我们在微博发表评论的时候,我们不用刷新页面,就能看到相关位置出现我们刚刚评论的信息。在实际项目中就类似,我们新增一条信息,我们不用重新刷新页面,就能显示我们的刚刚新增的信息,大大增加了用户的体验好感度。
四、如何使用ajax
在使用ajax之前还需要了解一个名词 XMLHttpRequest对象 ,XMLHttpReques对象是浏览器内置对象,用于与服务器之间的交互, 由此我们便可实现对网页的部分更新,而不是刷新整个页面。这个请求是异步的,即在往服务器发送请求时,并不会阻碍程序的运行,浏览器会继续渲染后续的结构。
4.1.XMLHttpRequest以异步的方式发送HTTP请求,因此在发送请求时,一样需要遵循HTTP协议。
4.1.1使用XMLHttpRequ对象发送一个get请求
- 创建一个XMLHttpRequest对象
var xhr = new XMLHttpRequest(); - 设置请求行
xhr.open(“get”,“url”);
第一个参数:请求方式 get/post
第二个参数:请求的地址 需要在url后面拼上参数列表 - 设置请求头
请求头中可以设置Content-Type,用以说明请求主体的内容是如何编码,get请求时没有请求体,无需设置 - 设置请求体
get请求的请求体为空,因为参数列表拼接到url后面了
4.1.2使用XMLHttpRequest对象发送一个post请求
- 创建一个XMLHttpRequest对象
var xhr = new XMLHttpRequest(); - 设置请求行
xhr.open(“post”,“url”)
第一个参数:请求方式 get/post
第二个参数:请求地址,post请求列表在请求体中 - 设置请求头, post 请求必须要设置 content-type, 标记请求体内容的解析方式, 不然后端无法解析获取数据
xhr.setRequestHeader( “content-type”, “application/x-www-form-urlencoded” ); - 设置请求体
xhr.send( “name=XiaoMing&age=18” );
注意事项: - post请求, 设置请求行时, 不拼接参数列表
- post必须设置请求头中的content-type为application/x-www-form-urlencoded, 标记请求体解析方式
- post 请求需要将参数列表设置到请求体中
4.2获取响应readyState
readyState:记录了XMLHttpRequest对象的当前状态
readyState有五种可能的值:
xhr.readyState = 0时,UNSENT open尚未调用
xhr.readyState = 1时,OPENED open已调用
xhr.readyState = 2时,HEADERS_RECEIVED 接收到头信息
xhr.readyState = 3时,LOADING 接收到响应主体
xhr.readyState = 4时,DONE 响应完成
HTTP响应分为3个部分,状态行、响应头、响应体。
给xhr注册一个onreadystatechange事件,当xhr的状态发生状态发生改变时,会触发这个事件
xhr.onreadystatechange = function () {
if(xhr.readyState == 4){
//1. 获取状态行
console.log("状态行:"+xhr.status);
//2. 获取响应头
console.log("所有的响应头:"+xhr.getAllResponseHeaders());
console.log("指定响应头:"+xhr.getResponseHeader("content-type"));
//3. 获取响应体
console.log(xhr.responseText);
}
}
关键词:XMLHttpRequest readyState responseText
五、相关案例
5.1实时判断用户名是否存在
使用php编写的服务器代码:
<?php
$username = $_GET['username']; // 获取到前端传递过来的用户名
// 模拟数据库, 假设数据库中只有这些人的名字
$dbArr = [ 'aa', 'bb', 'cc', "dd" ];
// in_array( $content, $arr ) // 作用: 判断 $content 在 $arr 中是否存在。如果存在, 返回 true, 如果不存在, 返回false
// 需求: 如果 $username 在 $dbArr 中存在, 用户已存在, 返回 yes
// 如果 $username 不在 $dbArr 中, 用户名不存在, 返回 no
if ( in_array( $username, $dbArr ) ) {
// 用户名已存在
echo "yes";
}
else {
// 用户名不存在
echo "no";
}
?>
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<input type="text" id="inp"> <span id="msg"></span>
<script>
// 实现效果: input框失去焦点, 提示用户, 该用户名是否可以注册
// 思路:
// 1. 给 input 框注册 onblur
// 2. 获取 input 框的 value 值
// 3. 发送 get 请求到后台, 要传参
// 4. 后台处理 get 请求, 判断该用户名是否存在 in_array( $content, $arr )
// (1) 如果已存在, 返回 yes
// (2) 如果不存在, 返回 no
// 5. 前端处理响应, 根据 yes/no 提示用户
var inp = document.getElementById("inp");
var msg = document.getElementById("msg");
inp.onblur = function() {
// 获取 input 的值
var value = inp.value.trim();
if ( value === "" ) {
// 说明用户没有输入内容, 提示用户请输入用户名
msg.innerHTML = "请输入用户名";
msg.style.color = "red";
return;
}
// 1. 发送 get 请求到后台
var xhr = new XMLHttpRequest();
// 请求行 请求头 请求体
xhr.open( "get", "07-hasUser.php?username=" + value );
// get 不需要设置请求头, 且没有请求体
xhr.send( null );
// 2. 处理响应
xhr.onreadystatechange = function() {
if ( xhr.readyState === 4 ) { // 响应完成
if ( xhr.status === 200 ) { // 响应成功
console.log( xhr.responseText );
var result = xhr.responseText; // yes/no
if ( result === "yes" ) {
// 用户名已存在
msg.innerHTML = "用户名已存在";
msg.style.color = "red";
}
if ( result === "no" ) {
// 用户名不存在
msg.innerHTML = "该用户可以注册";
msg.style.color = "green";
}
}
}
}
}
</script>
</body>
</html>
5.2处理post请求,登录案例
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<!-- 引入样式 -->
</head>
<body>
用户名:<input type="text" id="userInp"><br>
密码:<input type="password" id="passInp"><br>
<button id="btn">登录</button>
<script>
var userInp = document.getElementById("userInp");
var passInp = document.getElementById("passInp");
var btn = document.getElementById("btn");
btn.onclick = function(){
var username = userInp.value;
var password = passInp.value;
var xhr = new XMLHttpRequest;
xhr.open("post","post.php");
xhr.setRequestHeader("content-type","application/x-www-form-urlencoded");
xhr.send("username=" + username + "&password=" + password );
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 ){
if(xhr.status === 200){
console.log(xhr.responseText);
var result = xhr.responseText;
if(result === '0'){
location.href = "qwer.html";
}
if(result === '1' ){
alert("密码错误");
}
if(result === '2' ){
alert("用户名错误");
}
if(result === '3' ){
alert("用户名和密码错误");
}
}
}
}
}
</script>
</body>
</html>
PHP服务器端代码:
<?php
$username = $_POST['username'];
$password =$_POST['password'];
if($username === "aa" && $password === "123456" ){
echo "0";
}
else if( $username === "aa" && $password !== "123456"){
echo "1";
}
else if( $username !== "aa" && $password === "123456"){
echo "2";
}else{
echo "3";
}
?>
5.3聊天机器人案例
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Ajax</title>
<style>
body {
margin: 0;
padding: 0;
background-color: #F7F7F7;
}
h3 {
text-align: center;
}
.chatbox {
width: 500px;
height: 500px;
margin: 0 auto;
border: 1px solid #CCC;
background-color: #FFF;
border-radius: 5px;
}
.messages {
height: 350px;
padding: 20px 40px;
box-sizing: border-box;
border-bottom: 1px solid #CCC;
overflow: scroll;
}
.messages h5 {
font-size: 20px;
margin: 10px 0;
}
.messages p {
font-size: 18px;
margin: 0;
}
.self {
text-align: left;
}
.other {
text-align: right;
}
.form {
height: 150px;
}
.form .input {
height: 110px;
padding: 10px;
box-sizing: border-box;
}
.form .btn {
height: 40px;
box-sizing: border-box;
border-top: 1px solid #CCC;
}
.form textarea {
display: block;
width: 100%;
height: 100%;
box-sizing: border-box;
border: none;
resize: none;
outline: none;
font-size: 20px;
}
.form input {
display: block;
width: 100px;
height: 30px;
margin-top: 5px;
margin-right: 20px;
float: right;
}
</style>
</head>
<body>
<h3>简单的Ajax实例</h3>
<div class="chatbox">
<!-- 聊天内容 -->
<div class="messages">
<div class="self">
<h5>我说</h5>
<p>你好</p>
</div>
<div class="other">
<h5>对方说</h5>
<p>你好</p>
</div>
</div>
<div class="form">
<div class="input">
<textarea></textarea>
</div>
<div class="btn">
<input type="button" value="发送" id='btn'>
</div>
</div>
</div>
<script>
// 聊天机器人思路:
// 1. 给发送按钮, 添加点击事件
// 2. 获取 textarea 里面内容, 动态创建 "我说" 结构, div 类名 self, 追加到 messages 中
// 3. 发送请求到后台, 后台返回一个随机的文本
// 4. 前端处理响应, 动态创建 "他说" 结构, div 类名 other, 追加到 messages 中
var btn = document.getElementById("btn");
// document.querySelector( "选择器" ); 返回一个 dom 对象
// html5 中新增的获取元素方法
var textarea = document.querySelector(".input > textarea"); // 获取到 textarea
var messages = document.querySelector(".messages"); // 获取到 messages
btn.onclick = function() {
// 获取 textarea 的内容, 表单元素, 通过 value 来获取内容
var content = textarea.value;
// 动态创建我说结构, div 类名 self, 追加到 messages 中
var div = document.createElement( "div" );
div.className = "self";
div.innerHTML = "<h5>我说</h5><p>" + content + "</p>";
messages.appendChild( div );
// 让 dom 元素滚动到可视区域内
div.scrollIntoView();
// 清空 textarea 内容
textarea.value = "";
// 1. 发送 get 请求, 将 content 传递过去 (可不传)
var xhr = new XMLHttpRequest();
xhr.open( "get", "09-talking.php?content=" + content );
xhr.send( null );
// 2. 监听处理响应
xhr.onreadystatechange = function() {
if ( xhr.readyState === 4 ) {
if ( xhr.status === 200 ) {
// 响应成功
// xhr.responseText 获取响应文本
var result = xhr.responseText;
// 动态创建他说结构, div 类名 other, 追加到 messages 中
var div = document.createElement("div");
div.className = "other";
div.innerHTML = "<h5>对方说</h5><p>" + result + "</p>";
messages.appendChild( div );
// 让 dom 元素滚动到可视区域内
div.scrollIntoView();
}
}
}
}
</script>
</body>
</html>
PHP服务器代码:
<?php
header("content-type:text/html;charset=utf-8");
$results = array(
"吃药了没?",
"不约。。",
"爱过",
"你今天长的真帅!",
"这你也信",
"曾经有一份真挚的爱情摆在我面前,我却没有珍惜",
"情不知所以,一往而深",
"陪伴是最长情的告白",
"死鬼, 一般去~",
"流氓!"
);
// array_rand: 随机获取数组的一个下标
$random = array_rand( $results, 1 );
// sleep 模拟网络延迟
sleep(1);
echo $results[$random];
?>