国强极客
有问题请加微信:guoqiang7585
国强极客

Ajax(1) 基础 表单验证 省市联动

Ajax(1) 基础 表单验证 省市联动

代码位置:全栈教程/04_JS/JS核心第10Ajax第1天/代码/2018-09-13

二、今日目标

  • 1、知道Ajax能够做什么
  • 2、理解Ajax的工作原理
  • 3、能够创建兼容各个浏览器的Ajax对象
  • 4、能够通过get和post方式发送Ajax请求
  • 5、能够用代码写出一次Ajax请求的全部过程
  • 6、能够解决IE缓存
  • 7、能够理解同步和异步请求的区别
  • 8、知道什么是JSON以及它用什么作用
  • 9、能够将JSON数据和PHP数据相互转化
  • 10、能够将JSON数据和JS数据相互转化
  • 11、Ajax请求能够处理服务器返回的JSON格式的数据

三、概述

手册位置:W3C手册 — 上面的JavaScript — 左侧的Ajax

1、Ajax历史

1999年,微软在IE5上使用,但是没有被认知。
2005年,谷歌的使用(地图、gmail),使得ajax被全世界所认识,并广泛使用。

2、Ajax是什么

Ajax中的第一个A是Asynchronous [eɪˈsɪŋkrənəs]
(异步)JavaScript and XML的缩写。可以看出它不是一种技术,而是多种技术的综合体。
其中有JavaScript、有xml、有json、有html、有css、有dom、有XMLHttpRequest对象等等。
XMLHttpRequest对象,也叫做Ajax对象,浏览器中自带的对象。
Ajax的工作也是基于http协议的。

3、Ajax能做什么

①、提高用户体验。
②、表单时时验证

③、百度地图、谷歌地图
④、网页版的聊天室
⑤、无刷新的分页

五、XMLHttpRequest对象介绍

1、创建xhr对象(ajax对象)

所有现代浏览器均支持 XMLHttpRequest 对象(IE5 和 IE6 使用 ActiveXObject)。

 var xhr = new XMLHttpRequest(); //IE6+
    //var xhr = new ActiveXObject('Microsoft.XMLHTTP'); //ie5/IE6
    console.log(xhr);

2、主要的成员属性:

readyState:表示xhr工作进行到何种状态

onreadystatechange:事件,表示readyState改变的时候触发的事件

status:http状态码

responseText:用来接收返回的文本类型的数据

responseXML:用来接收返回的是XML格式的数据

3、主要的方法:

open():设置(定义)一个请求

send():发送设置好的请求

setRequestHeader():设置ajax请求头信息

六、使用Ajax的步骤

完成验证用户名案例,要求用户名唯一,就是不能有重复。
页面中有一个文本框,当失去焦点的时候,验证输出的内容是否已经存在。

1、创建所需文件

创建03chkusername.html:

<input type="text" id="username" /> <span id="msg"></span>

创建03chkusername.php

//工作是:验证提交用户输入的用户名是否已经被注册
//为了简化,模拟用户'zhangsan'、'lisi'、‘wangwu’ 已经被注册,其他用户名都可用
$arr = ['zhangsan','lisi', 'wangwu', 'aaa', 'bbb','ccc','ddd','fff', 'ggg'];

2、当input失去焦点,准备发送


因为用get方式请求,所以参数直接写到url上即可。服务器端获取地址栏的参数,同样使用$_GET来获取。

3、发送请求

调用Ajax对象的send方法发送请求到服务器。

4、服务器接收数据并判断


判断完成,将判断的结果返回给浏览器。echo出来的东西就是返回给浏览器的内容。
测试:

5、接收服务器返回的数据,并处理


经过测试,发现并没有成功接收到服务器返回的数据。通过console.log(result);查看到的结果什么都么有。

6、监听Ajax执行状态

发送请求完毕,不应该马上就接收服务器返回的数据,应该判断一下Ajax进行到哪一步了。如果说进行到最后一步了,即服务器返回数据完毕,这个时候才应该获取服务器返回的数据。
Ajax对象中用onreadystatechange属性(事件),来监听(检测)Ajax执行到哪一步了。
Ajax对象中用readyState属性来表示Ajax的状态,具体是readyState属性值如下:

源代码:

03chkusername.html

<input type="text" id="username" /> <span id="msg"></span>

<script>


    //当input失去焦点的时候,发送请求
    document.getElementById('username').onblur = function(){
        //第一步:创建Ajax对象
        var xhr = new XMLHttpRequest();
        //第二步:准备工作
        var uname = this.value; //要发送给服务器的用户名
        //xhr.open(请求方式, 请求的地址, 同步或异步); //该方法用于发送请求前的准备工作
        xhr.open('get', '03chkusername.php?u=' + uname, true); //true表示异步,默认也是true
        //第三步:发送请求到服务器
        xhr.send(); //send的参数表示post请求的参数,因为我们用的是get请求,所以参数不用填
        //当xhr执行的时候,如果状态发生变化,就会触发事件
        xhr.onreadystatechange = function(){
            //readyState可能是变化有:0~1/1~2/2~3/3~4
            if(xhr.readyState == 4){
                //表示服务器完全返回了数据,这时才应该接收数据并处理
                //第四步:接收服务器返回的数据,并处理
                var result = xhr.responseText; //用responseText来接收服务器返回的文本类型的信息
                console.log(result); //输出结果,什么都没有,即不是1,也不是0
                if(result == 1){
                    document.getElementById('msg').innerHTML = '<font color="red">sorry,用户名已存在</font>';
                }else if(result == 0){
                    document.getElementById('msg').innerHTML = '<font color="green">恭喜,用户名可用</font>';
                }
            }
        };

    };

</script>

03chkusername.php

//header("Cache-Control:no-cache");
//header("Pragma:no-cache");
//header("Expires:-1");

//工作是:验证提交用户输入的用户名是否已经被注册
//为了简化,模拟用户'zhangsan'、'lisi'、‘wangwu’ 已经被注册,其他用户名都可用
$arr = ['zhangsan','lisi', 'wangwu', 'aaa', 'bbb','ccc','ddd','fff', 'ggg'];

//接收发送过来的数据,并判断
$u = $_GET['u'];
//判断
if(in_array($u, $arr)){
    //说明用户名已经存在
    echo 1;
}else{
    //说明用户名可用
    echo 0;
}

7、使用Ajax步骤总结

七、细节问题

1、编码字符

为什么要编码:

解决的办法就是对用户输入的内容进行编码。

encodeURI() — 不能对“:/=&”进行编码,能对汉字进行编码

encodeURIComponent() — 能对“:/=&”进行编码,也能对汉字进行编码


一般情况下,JS编码后发送到服务器,PHP会自动解码,如果没有自动解码,用PHP的函数urldecode来解码。

2、缓存处理

什么是Ajax缓存原理?
Ajax在发送的数据成功后,会把请求的URL和返回的响应结果保存在浏览器缓存内,当下一次调用Ajax发送相同的请求时,它会直接从缓存中把数据取出来,这是为了提高页面的响应速度和用户体验。当前这两次请求URL完全相同,包括参数。这个时候,浏览器就不会与服务器交互
两次请求的地址完全一致(包括参数),那么IE就会从缓存中取服务器上一次返回的结果。而不会从新向服务器发送请求。
测试方法:
先输入一个不存在的用户名,比如bbb,失去焦点,发送一次Ajax请求,然后不刷新页面。打开php文件,向数组中加入用户名bbb。回到浏览器,还不能刷新,再次失去焦点。如下图

如何解决IE缓存的问题:

1、在ajax发送请求前加上

 xhr.setRequestHeader("If-Modified-Since","0"); //实测可用

2、在服务器端加

header("Cache-Control:no-cache");
header("Pragma:no-cache");
header("Expires:-1");

加入三个header,目的是让所有的浏览器都不缓存。

3、在 Ajax 的 URL 参数后加上

 "?fresh=" + Math.random(); //当然这里参数 fresh 可以任意取了

4、第种方法和第3种类似,在 URL 参数后加上 "?timestamp=" + new Date().getTime();

5、用POST替代GET:不推荐

以上几种方式,比较推荐第3和第4中方法。

3、get和post请求

使用POST请求:
xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");

服务器接收数据用$_POST.

ajax中的get和post的一些说明:
①、用post请求,不会产生缓存。
②、用post请求的时候,能不能也用get,即post和get请求同时使用。答案是能,只不过get请求的参数用\(_GET获取,post请求的参数用\)_POST获取。
③、用$_REQUEST获取get和post方式提交的参数,如果参数名相同,获取的是谁?获取的是post的内容

4、同步、异步

同步请求,在同一个时间点上,只能有一个进程;其他进程只能等待。
异步请求,在同一个时间点上,可以同时进行多个进程。
open方法的第三个参数表示同步或者是异步请求。默认值true表示异步请求,false表示同步请求。

5、请求的url如果出错怎么办


以后写Ajax的时候,不但要判断readyState的值是否为4,还要判断http状态码status属性的值是否是200.

八、JSON

w3c手册位置:上面的javascript – 左侧的JSON

1、什么是json

json本质就是字符串,只不过这个字符串的格式有要求,格式要符合js中的数组或对象的格式

 "['apple', 'orange', 'banana']"
"{name:'zhangsan', age:20}"


更加复杂的情况:

"[{id:1, name:'宋江', age:30}, { id:2, name:'卢俊义', age:30}, { id:3, name:'吴用', age:30}]"

2、JSON有什么用

json在web开发中,它起到的作用和xml和的作用一样。具体来说,json可以当做配置文件,json文件可以存储数据,
json可以当做两种编程语言交换数据的媒介。

3、json和PHP进行转换

1、把PHP数据转化成json格式

使用json_encode()函数

$arr1 = ['apple', 'banana', 'pear'];
$arr2 = ['one'=>'LiuBei', 'two'=>'GuanYu', 'three'=>'CaoHao'];

//把上面两个数组,转换成JSON
$str1 = json_encode($arr1);
echo $str1; // ["apple","banana","pear"]
echo '<br>';
$str2 = json_encode($arr2);
echo $str2; // {"one":"LiuBei","two":"GuanYu","three":"CaoHao"}

//将str1和str2转成PHP数据
echo '<pre>';
print_r(json_decode($str1));
print_r(json_decode($str2, true));//加入true表示转回数组格式,否则默认对象形势

2、把json格式数据转化成PHP数据

json_decode(数组,true);//加入true表示转回数组格式,否则默认对象形势

4、json和JavaScript进行转换

1、把js数据转化成json

使用的方法是JSON对象的stringify()方法。

2、把json数据转化成js数据

方法一是使用JSON.parse(json字符串)方法;

方法二是使用eval函数。

5、小结

九、Ajax中,服务器返回json格式的数据

创建07json.html,向07json.php发送ajax请求。

服务器中的07json.php,返回一个数组。但是PHP的数据和JS的数组不一样,所以要转换成JSON格式,然后再返回:

再看07json.html,接收到服务器返回的数据(JSON格式),然后通过JSON.parse转换JS数据,就可以处理。

十、案例–省市县三级联动

1、资料说明

08city.sql 资料中,包含三张表,sheng、shi、xian。

查询所有的省:

select * from sheng;

查询河北省中的市:

select * from shi where ProvinceCode = 130000;

查询石家庄市的县:

select * from xian where CityCode = 130100;

2、创建所需文件

08city.html:

<select id="sheng">
    <option value="0">--请选择省--</option>
</select>

<select id="shi">
    <option value="0">--请选择市--</option>
</select>

<select id="xian">
    <option value="0">--请选择县--</option>
</select>


08city.php,接收到浏览器发来的Ajax请求,连接数据库,获取省。获取完毕,转换成JSON类型返回给浏览器:

JS接收服务器返回的数据,并处理成JS数组,然后创建option,给option赋值value属性,并添加到select框中:
做这块的时候,要经常通过浏览器工具来查看错误。

最终效果是:

/全栈教程/04_JS/JS核心第11Ajax第2天

4、省切换的时候,获取市

给sheng绑定事件,执行Ajax请求:

PHP代码:

浏览器检测,没有问题。下面处理返回的结果:

5、市切换的时候,获取县

HTML代码:

PHP代码:

一个问题,省切换的时候,不但要重置市,还有重置县:

四、优化省市县三级联动

1、将数据库修改为文件

省市县的数据,不会经常变动,基本上可以认为是不变的数据。对于这样的数据,最好不要存到数据库,用文件存放也是一样的,而且用文件存放还可以减轻数据库的压力。所以用文件把省市县的数据存储,然后去查文件。

2、简化PHP代码

复制02city.html为03city.html。复制02city.php为03city.php
复制city文件夹到项目中:

查询省、市、县的时候都根据文件名去查找,并且约定浏览器请求的时候,要传递filename参数,参数的值就是文件名。

3、修改JS代码


4、简化JS代码

封装\(、chuli、get三个函数:
\) : 根据元素的id,返回dom对象
chuli : 传入要处理的数据,并且传入要放入的位置。
get :执行ajax请求,参数1是url地址,参数2是一个函数,用于处理服务器返回的数据。
chuli函数:

\(函数
![-w636](media/15714037815352/15714686776758.jpg)
get函数
![-w856](media/15714037815352/15714686873343.jpg)省市县获取代码:
![-w862](media/15714037815352/15714686985015.jpg)
==写的\)、get函数做什么项目都可以使用,可以将这两个函数写到一个js文件中。==

赞赏
对内容有疑问,请加我微信:guoqiang7585
# # #
首页      全栈教程      JavaScript      Ajax(1) 基础 表单验证 省市联动

国强极客

文章作者

博客站长,有问题请加微信【guoqiang7585】。

国强极客

Ajax(1) 基础 表单验证 省市联动
代码位置:全栈教程/04_JS/JS核心第10Ajax第1天/代码/2018-09-13 二、今日目标 1、知道Ajax能够做什么 2、理解Ajax的工作原理 3、能够创建兼容各个浏览器的Ajax对象 4、能够通过get和p…
扫描二维码继续阅读
2019-12-15