1
0
mirror of https://github.com/Daotin/Web.git synced 2024-11-01 05:24:46 +08:00
Web-main/06-Ajax/07-接口文档,验证用户名唯一性案例.md
2020-12-30 11:39:04 +08:00

485 lines
18 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

需求:使用接口文档验证用户名、邮箱、手机的唯一性
## 1、接口文档
当前端界面需要从服务器获取数据的时候,其实就是眼访问一个 URL 地址,指定特定的参数即可。这个 URL 对应的是 php 或者 jsp 等都是服务器开发人员已经开发好了。服务器开发人员开发好相关的接口之后,会提供一份接口文档给前端开发人员,在接口中会详细说明你要获取什么数据,访问什么地址,传入什么参数等等内容,下面就是一个简单接口文档的内容:
**验证用户名唯一性的接口**
| 地址 | /server/checkUsername.php |
| ------- | --------------------------------- |
| 作用描述 | 验证用户名是否可用 |
| 请求类型 | get 请求 |
| 参数 | uname |
| 返回的数据格式 | 普通字符串 |
| 返回数据说明 | 返回 ok代表用户名可用 返回 error代表用户名不可用。 |
**验证邮箱唯一性的接口**
| 地址 | /server/checkEmail.php |
| ------- | -------------------------- |
| 作用描述 | 验证邮箱是否可用 |
| 请求类型 | post 请求 |
| 参数 | e |
| 返回的数据格式 | 数字 |
| 返回数据说明 | 返回 0代表邮箱可用 返回 1代表邮箱不可用。 |
**验证手机号唯一性的接口**
| 地址 | /server/checkPhone.php |
| ------- | ---------------------- |
| 作用描述 | 验证手机号是否可用 |
| 请求类型 | post 请求 |
| 参数 | phonenumber |
| 返回的数据格式 | json格式 |
| 返回数据说明 | 如下: |
```
手机号可用情况下返回如下:
{
"status":0,
"message":{
"tips":"手机号可用",
"phonefrom":"中国电信"
}
}
手机号不可用情况下返回如下:
{
"status":1,
"message":"手机号已被注册"
}
```
## 2、示例代码
```html
<!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>
<div id="dv">
<h1>用户注册</h1>
用户名:<input type="text" name="username"><span id="user-span"></span><br>
邮箱:<input type="text" name="email"><span id="email-span"></span><br>
手机:<input type="text" name="phone"><span id="phone-span"></span><br>
</div>
<script>
// 获取所有元素
var userObj = document.getElementsByName("username")[0];
var emailObj = document.getElementsByName("email")[0];
var phoneObj = document.getElementsByName("phone")[0];
var userSpanObj = document.getElementById("user-span");
var emailSpanObj = document.getElementById("email-span");
var phoneSpanObj = document.getElementById("phone-span");
//用户名文本框失去焦点事件
userObj.onblur = function () {
// 获取文本内容
var userText = this.value;
var xhr = new XMLHttpRequest();
xhr.open("get", "./server/checkUsername.php?uname="+userText, true);
xhr.send(null);
xhr.onreadystatechange = function () {
if(this.readyState == 4) {
if(this.status == 200) {
if(this.responseText == "ok") {
userSpanObj.innerHTML = "用户名可用";
} else if(this.responseText == "error") {
userSpanObj.innerHTML = "用户名不可用";
}
}
}
};
};
//邮箱文本框失去焦点事件
emailObj.onblur = function () {
// 获取文本内容
var emailText = this.value;
var xhr = new XMLHttpRequest();
xhr.open("post", "./server/checkEmail.php", true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send("e="+emailText);
xhr.onreadystatechange = function () {
if(this.readyState == 4) {
if(this.status == 200) {
console.log(this.responseText);
if(this.responseText == 0) {
emailSpanObj.innerHTML = "邮箱可用";
} else if(this.responseText == 1) {
emailSpanObj.innerHTML = "邮箱不可用";
}
}
}
};
};
//手机号文本框失去焦点事件
phoneObj.onblur = function () {
// 获取文本内容
var phoneText = this.value;
var xhr = new XMLHttpRequest();
xhr.open("post", "./server/checkPhone.php", true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send("phonenumber="+phoneText);
xhr.onreadystatechange = function () {
if(this.readyState == 4) {
if(this.status == 200) {
var val = JSON.parse(this.responseText);
// console.log(val.status);
if(val.status == 0) {
phoneSpanObj.innerHTML = val.message.tips + " " + val.message.phonefrom;
} else if(val.status == 1) {
phoneSpanObj.innerHTML = val.message;
}
}
}
};
};
</script>
</body>
</html>
```
> 书写以上代码的过程中,完全不需要查看对应的 php 文件,只需要查看接口文档就可以搞定。
**注意:**
上面手机号文本框失去焦点事件中responseText 返回的内容永远是字符串如果要取得字符串里面的json需要使用关键字JSON.parse来转换。
JSON.parse 表示把字符串类型的json转换成json数据格式但是转换的时候可能会出现下面的错误
![](./images/1.png)
出现错误提示“Uncaught SyntaxError: Unexpected token u in JSON at position 2”
如果出现了这个错误就表示这个字符串无法转成json格式的数据。
json 数据的格式必须要求属性名一定要用双引号(不能是单引号)包裹起来,必须!
而上面的第一个 username 没有用双引号括起来,所以报错。
## 3、代码封装
上面验证用户名,邮箱和手机号的时候,都是使用的 Ajax 的四部操作,有很多代码冗余,所以将 Ajax 的四步操作封装在一个函数中很有必要的。
```html
<!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>
<div id="dv">
<h1>用户注册</h1>
用户名:<input type="text" name="username"><span id="user-span"></span><br>
邮箱:<input type="text" name="email"><span id="email-span"></span><br>
手机:<input type="text" name="phone"><span id="phone-span"></span><br>
</div>
<script>
// Ajax 四步操作的封装函数
function myAjax(type, url, param, async, dataType, callback) {
var xhr = null;
// 兼容性处理
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
if((type == "get") || (type == "GET")) {
if(param && param != "") {
url += "?" + param;
}
xhr.open(type, url, async);
xhr.send(null);
} else if((type == "post") || (type == "POST")) {
xhr.open(type, url, async);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(param);
}
if(async) {
xhr.onreadystatechange = function () {
if(this.readyState == 4) {
if(this.status == 200) {
if(dataType == "xml") {
callback(this.responseXML);
} else if(dataType == "json") {
callback(JSON.parse(this.responseText));
} else {
callback(this.responseText);
}
}
}
};
} else {
if(this.readyState == 4) {
if(this.status == 200) {
if(dataType == "xml") {
callback(this.responseXML);
} else if(dataType == "json") {
callback(JSON.parse(this.responseText));
} else {
callback(this.responseText);
}
}
}
}
}
// 获取所有元素
var userObj = document.getElementsByName("username")[0];
var emailObj = document.getElementsByName("email")[0];
var phoneObj = document.getElementsByName("phone")[0];
var userSpanObj = document.getElementById("user-span");
var emailSpanObj = document.getElementById("email-span");
var phoneSpanObj = document.getElementById("phone-span");
//用户名文本框失去焦点事件
userObj.onblur = function () {
// 获取文本内容
var userText = this.value;
myAjax("get", "./server/checkUsername.php", "uname="+userText, "true", "text", function (result) {
if(result == "ok") {
userSpanObj.innerHTML = "用户名可用";
} else if(result == "error") {
userSpanObj.innerHTML = "用户名不可用";
}
});
};
//邮箱文本框失去焦点事件
emailObj.onblur = function () {
// 获取文本内容
var emailText = this.value;
myAjax("post", "./server/checkEmail.php", "e="+emailText, "true", "text", function (result) {
if(result == 0) {
emailSpanObj.innerHTML = "邮箱可用";
} else if(result == 1) {
emailSpanObj.innerHTML = "邮箱不可用";
}
});
};
//手机号文本框失去焦点事件
phoneObj.onblur = function () {
// 获取文本内容
var phoneText = this.value;
myAjax("post", "./server/checkPhone.php", "phonenumber="+phoneText, "true", "json", function (result) {
if(result.status == 0) {
phoneSpanObj.innerHTML = result.message.tips + " " + result.message.phonefrom;
} else if(result.status == 1) {
phoneSpanObj.innerHTML = result.message;
}
});
};
</script>
</body>
</html>
```
**仍然存在的问题**
1、参数的顺序不可改变
2、参数没有默认值所有的参数必须传递。
## 4、代码进一步封装
将需要传入的参数做成一个对象,这个对象所有的有默认参数,如果没有传入一些参数的话,使用默认参数代替;如果传入了相关参数,则覆盖掉默认参数。
```html
<!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>
<div id="dv">
<h1>用户注册</h1>
用户名:<input type="text" name="username"><span id="user-span"></span><br>
邮箱:<input type="text" name="email"><span id="email-span"></span><br>
手机:<input type="text" name="phone"><span id="phone-span"></span><br>
</div>
<script>
function myAjax2(obj) {
var defaults = {
type: "get",
url: "#",
dataType: "",
data: {}, // 参数有可能多个,用对象保存
async: true,
success: function (result) {
console.log(result);
}
};
for(var key in obj) {
defaults[key] = obj[key];
}
var xhr = null;
if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
var param = "";
for(var attr in defaults.data) {
param += attr + "=" + defaults.data[attr] + "&" // 比如uname=zhangsan&pwd=123
}
// 最后一个参数后面去掉 &
if(param) {
param = param.substring(0, param.length-1);
}
if((defaults.type == "get") || (defaults.type == "GET")) {
defaults.url += "?" + param;
}
xhr.open(defaults.type, defaults.url, defaults.async);
if((defaults.type == "get") || (defaults.type == "GET")) {
xhr.send(null);
} else if((defaults.type == "post") || (defaults.type == "POST")) {
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send(param);
}
if(defaults.async) {
xhr.onreadystatechange = function () {
if(this.readyState == 4) {
if(this.status == 200) {
if(defaults.dataType == "xml") {
defaults.success(this.responseXML);
} else if(defaults.dataType == "json") {
defaults.success(JSON.parse(this.responseText));
} else {
defaults.success(this.responseText);
}
}
}
};
} else {
if(this.readyState == 4) {
if(this.status == 200) {
if(defaults.dataType == "xml") {
defaults.success(this.responseXML);
} else if(defaults.dataType == "json") {
defaults.success(JSON.parse(this.responseText));
} else {
defaults.success(this.responseText);
}
}
}
}
}
// 获取所有元素
var userObj = document.getElementsByName("username")[0];
var emailObj = document.getElementsByName("email")[0];
var phoneObj = document.getElementsByName("phone")[0];
var userSpanObj = document.getElementById("user-span");
var emailSpanObj = document.getElementById("email-span");
var phoneSpanObj = document.getElementById("phone-span");
//用户名文本框失去焦点事件
userObj.onblur = function () {
myAjax2({
url: "./server/checkUsername.php",
type: "get",
data: {uname: this.value},
success: function (result) {
if(result == "ok") {
userSpanObj.innerHTML = "用户名可用";
} else if(result == "error") {
userSpanObj.innerHTML = "用户名不可用";
}
}
});
};
//邮箱文本框失去焦点事件
emailObj.onblur = function () {
myAjax2({
url: "./server/checkEmail.php",
type: "post",
data: {e: this.value},
success: function (result) {
if(result == 0) {
emailSpanObj.innerHTML = "邮箱可用";
} else if(result == 1) {
emailSpanObj.innerHTML = "邮箱不可用";
}
}
});
};
//手机号文本框失去焦点事件
phoneObj.onblur = function () {
myAjax2({
url: "./server/checkPhone.php",
type: "post",
dataType: "json",
data: {phonenumber: this.value},
success: function (result) {
if(result.status == 0) {
phoneSpanObj.innerHTML = result.message.tips + " " + result.message.phonefrom;
} else if(result.status == 1) {
phoneSpanObj.innerHTML = result.message;
}
}
});
};
</script>
</body>
</html>
```
> 进一步封装后的函数为: myAjax2({}) 里面是一个对象。使用默认对象的方式,不仅可以解决传入参数顺序不一致的问题;还可以解决不传参数时默认值的问题。