现在一般最多兼容到 IE8, 这里以后见到了知道是在处理兼容性就行了
var xhr = null;
if(XMLHttpRequest){
//现代浏览器 IE7+
xhr = new XMLHttpRequest();
}else{
//老版本的 Internet Explorer (IE5 和 IE6)使用 ActiveX 对象:
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}
每次发送ajax请求,其实步骤都是一样的,重复了大量代码,我们完全可以封装成一个工具函数。
//1. 创建xhr对象
//2. 设置请求行
//3. 设置请求头
//3. 设置请求体
//4. 监听响应状态
//5. 获取响应内容
参数名 | 参数类型 | 描述 | 传值 | 默认值 |
---|---|---|---|---|
type | string | 请求方式 | get/post | 只要不传post,就是get |
url | string | 请求地址 | 接口地址 | 如果不传地址,不发送请求 |
async | boolean | 是否异步 | true/fase | 只要不传false,那就是true,异步请求 |
data | object | 请求数据 | {key:value,key1:value2} | 需要把这个对象拼接成参数的格式 uname=hucc&upass=12345 |
dataType | string | 返回的数据类型 | xml/json/text | text |
success | function | 响应成功时调用 | - | - |
error | function | 响应失败时调用 | - | - |
// 要求参数obj必须传递,否则直接不发送请求
if(!obj || typeof obj !== "object"){
return;
}
// 如果type传递的是post,那就发送post请求,否则发送get请求
var type = obj.type == "post"?"post":'get';
var url = obj.url;
if(!url){
return;
}
// 只有当async传递了false,才会发送同步请求,不然只发送异步请求
var async = obj.async == false? false:true;
// 封装 ajax
// 目的: 发送 get 或者 post 请求
// 参数:
// type: 不传post, 就按get处理
// url: 必须传
// async: 不传false, 就按true处理
// data: 参数对象
// dataType: 数据类型, json/xml/text
// success: 成功的回调函数
// error: 失败的回调函数
// 命名空间: 将函数收录到一个对象中, 将来通过对象调用函数
var $ = {
ajax: function (options) {
// 参数处理
if (!options || typeof options != "object") { // 没传或者不是对象
return;
}
var type = options.type === "post" ? "post" : "get"; // 默认get
var url = options.url;
if (!url) {
return;
}
var async = options.async === false ? false : true; // true
var data = options.data; // 参数对象, 需要转换
var params = this.parse(data); // $.ajax => 方法调用模式, 谁调用方法, this就指向谁
var dataType = options.dataType;
var success = options.success;
var error = options.error;
// 发送请求
var xhr = new XMLHttpRequest();
if (type === "get") {
// 需要拼接参数
url = url + "?" + params;
params = null;
}
xhr.open(type, url, async);
// post请求需要设置请求头
if (type === "post") {
xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
}
xhr.send(params);
// 监听, 处理响应
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) { // 响应完成
if (xhr.status === 200) { // 响应成功
// 返回来的格式可能不一样
var result = null;
if (dataType === "xml") {
result = xhr.responseXML;
}
else if (dataType === "json") {
result = JSON.parse(xhr.responseText);
}
else {
result = xhr.responseText;
}
success && success(result);
}
else { // 响应失败
error && error(xhr.responseText);
}
}
}
},
parse: function (obj) {
if (!obj || typeof obj != "object") {
return null;
}
var arr = [];
for (var k in obj) {
arr.push(k + "=" + obj[k]); // name=pp
}
return arr.join("&");
}
};
【登录案例】
jQuery为我们提供了更强大的Ajax封装
参数列表
参数名称 | 描述 | 取值 | 示例 |
---|---|---|---|
url | 接口地址 | url:"02.php" | |
type | 请求方式 | get/post | type:"get" |
timeout | 超时时间 | 单位毫秒 | timeout:5000 |
dataType | 服务器返回的格式 | json/xml/text(默认) | dataType:"json" |
data | 发送的请求数据 | 对象 | data:{name:"zs", age:18} |
beforeSend | 调用前的回调函数 | function(){} | beforeSend:function(){ alert(1) } |
success | 成功的回调函数 | function (data) {} | success:function (data) {} |
error | 失败的回调函数 | function (error) {} | error:function(data) {} |
complete | 完成后的回调函数 | function () {} | complete:function () {} |
使用示例:
$.ajax({
type:"get",//请求类型
url:"02.php",//请求地址
data:{name:"zs", age:18},//请求数据
dataType:"json",//希望接受的数据类型
timeout:5000,//设置超时时间
beforeSend:function () {
//alert("发送前调用");
},
success:function (data) {
//alert("成功时调用");
console.log(data);
},
error:function (error) {
//alert("失败时调用");
console.log(error);
},
complete:function () {
//alert("请求完成时调用");
}
});
【案例:登录案例.html】
//$.post(url, callback, [dataType]);只发送post请求
//$.get(url, callback, [dataType]);
//$.getJSON(url, callback);
//$.getScript(url,callback);//载入服务器端的js文件
//$("div").load(url);//载入一个服务器端的html页面。
请求地址即所谓的接口,通常我们所说的接口化开发,其实是指一个接口对应一个功能, 并且严格约束了请求参数 和响应结果 的格式,这样前后端在开发过程中,可以减少不必要的讨论, 从而并行开发,可以极大的提升开发效率,另外一个好处,当网站进行改版后,服务端接口进行调整时,并不影响到前端的功能。
需求文档(产品)
总需求:点击获取验证码按钮,向服务端发送请求, 调用服务器端短信接口, 服务器端根据传参, 调用第三方短信接口, 给手机发送验证码
需求1:格式校验
(1) 手机号码不能为空 如果为空提示"手机号不能为空"
(2) 手机号码格式必须正确, 提示"请输入正确的手机号码"
需求2:点击发送时,按钮显示为"发送中",并且不能重复提交请求
需求3:根据不同的响应结果,进行响应。
(1)如果接口调用成功
如果响应代码为100,倒计时
如果响应代码为101,提示手机号重复
(2)如果接口调用失败,告诉用户"服务器繁忙,请稍候再试"
接口文档
接口说明:获取短信验证码
接口地址:getCode.php
请求方式:get
接口传参:mobile 手机号
返回类型 json
接口返回:{
"code":"101",
"msg":"手机号码存在",
"mobile":"18511249258"
}
参数说明: code 当前业务逻辑的处理成功失败的标识 100:成功 101:手机号码存在
msg 当前系统返回给前端提示
mobile 当前的手机号码
表单序列化 serialize
jquery提供了一个serialize()
方法序列化表单,说白就是将表单中带有name属性的所有参数拼成一个格式为name=value&name1=value1
这样的字符串。方便我们获取表单的数据。
//serialize将表单参数序列化成一个字符串。必须指定name属性
//name=pp&pass=123456&repass=123456&mobile=15751776629&code=1234
$('form').serialize();
jquery的ajax方法,data参数能够直接识别表单序列化的数据
$.post({
url:"register.php",
data:$('form').serialize(),
dataType:'json',
success:function (info) {
console.log(info);
}
});
需求文档
注册功能
总需求:点击注册按钮,向服务端发送请求
需求1:表单校验
1.1 用户名不能为空,否则提示"请输入用户名"
1.2 密码不能为空,否则提示"请输入密码"
1.3 确认密码必须与密码一直,否则提示"确认密码与密码不一致"
1.4 手机号码不能为空,否则提示"请输入手机号码";
1.5 手机号码格式必须正确,否则提示"手机号格式错误"
1.6 短信验证码必须是4位的数字,否则提示"验证码格式错误"
需求2:点击注册按钮时,按钮显示为"注册中...",并且不能重复提交请求
需求3:根据不同响应结果,处理响应
3.1 接口调用成功
100 提示用户注册成功,3s后跳转到首页
101 提示用户"用户名jepson已经存在"
102 提示用户"验证码错误"
3.2 接口调用失败,提示"服务器繁忙,请稍后再试",恢复按钮的值
接口文档
接口说明:注册
接口地址:register.php
请求方式:post
接口传参:name:用户名 pass:密码 code:验证码 mobile:手机号
返回类型 json
接口返回:{
"code":"100",
"msg":"注册成功",
"name":"Jepson"
}
参数说明:
code 当前业务逻辑的处理成功失败的标识 100:成功 101:用户存在 102:验证码错误
msg 当前系统返回给前端提示
name: 注册的用户名
是为了使用户界面与业务数据(内容)分离而产生的,它可以生成特定格式的文档,用于网站的模板引擎就会生成一个标准的HTML文档。
我们通过ajax获取到数据后,需要把数据渲染到页面,在学习模板引擎前,我们的做法是大量的拼接字符串,对于结构简单的页面,这么做还行
但是如果页面结构很复杂,使用拼串的话代码可阅读性非常的差,而且非常容易出错,后期代码维护也是相当的麻烦。
【演示:使用拼串进行渲染的缺点.html】
总结来说拼串渲染两大缺点:
github地址
中文api地址
1.引入模板引擎的js文件
<script src="template-web.js"></script>
2.准备模板
<!--
指定了type为text/html后,这一段script标签并不会解析,也不会显示。
-->
<script type="text/html" id="myTmp">
<p>姓名:隔壁老王</p>
<p>年龄:18</p>
<p>技能:查水表</p>
<p>描述:年轻力气壮</p>
</script>
3.准备数据
//3. 准备数据,数据是后台获取的,可以随时变化
var json = {
userName:"隔壁老王",
age:18,
skill:"查水表",
desc:"年轻气壮"
}
4.将模板与数据进行绑定
//第一个参数:模板的id
//第二个参数:数据
//返回值:根据模板生成的字符串。
var html = template("myTmp", json);
console.log(html);
5.修改模板
<script type="text/html" id="myTmp">
<p>姓名:{{userName}}</p>
<p>年龄:{{age}}</p>
<p>技能:{{skill}}</p>
<p>描述:{{desc}}</p>
</script>
6.将数据显示到页面
var div = document.querySelector("div");
div.innerHTML = html;
if语法
{{if gender='男'}}
<div class="man">
{{else}}
<div class="woman">
{{/if}}
each语法
<!--
1. {{each data}} 可以通过$value 和 $index获取值和下标
2. {{each data v i}} 自己指定值为v,下标为i
-->
{{each data v i}}
<li>
<a href="{{v.url}}">
<img src="{{v.src}}" alt="">
<p>{{v.content}}</p>
</a>
</li>
{{/each}}
//如果返回的数据是个数组,必须使用对象进行包裹,因为在{{}}中只写书写对象的属性。
var html = template("navTmp", {data:info});