需求描述

前端页面用户登录,ajax 发送请求,后台验证,并响应请求;


数据交互

前后分离,先后端再前端;

前端开发

login.html: 登录页面

index.html:   跳转页面

login.js:        前端请求页面

Web服务

server.js:    后端接口 node.js

登录过程

前端

1)前端要获取账号密码;

2)请求参数做签名加密;

3)发送登录请求;

后端

1)拿到参数;

2)验证返回;

后端服务

使用 node.js 的 express 框架来实现 web 服务并验证请求;

后端不是本贴的重点:只是为了完成前端的数据响应

需要安装 node.js  和引入 express 框架:

node.js 官网:​​​​https://nodejs.org/en/​

express 官网: ​​​​http://expressjs.com/​​​  或 ​​https://www.npmjs.com/package/express​​​

> npm install express -S
> npm install body-parser -S

新建 server.js : web 服务环境,

var express = require('express');   // 引入框架
var bodyParser = require('body-Parser'); // 引入依赖
var app = express();

// 数据解析
app.use(bodyParser.json()); // 对 json 数据解析
app.use(bodyParser.urlencoded({ extended: true })) // 对表单数据解析

// 跨域
var allowCrossDomain = function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*'); // 自定义中间件,设置跨域需要的响应头
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,OPTIONS,PUT,DELETE'); // 允许任何方法
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-Width,content-type,X-Session-Token');
next();
}
app.use(allowCrossDomain);

// 端口
app.listen(2999, function () {
console.log("sever has Started ............");
});

// 登录模拟接口 地址:http://localhost:2999/user/login
app.post('/user/login', function (req, resp) {
var { username, password } = req.body;
if (username && password) {
if (username == "admin" && password == "admin") {
resp.status(200).send("登录成功!");
} else {
resp.status(400).send("用户名或密码错误!");
}
} else {
resp.status(400).send("获取用户名或密码参数失败!");
}
});

启动后端服务:

> node server.js

javascript - 练习题:AJAX用户登录(nodejs服务响应)_express

启动后端服务后,显示:“sever has started ...  ” 代表正常启用,等待响应了;

测试接口: postman 来测试

postman 官网: ​​​​https://www.postman.com/​

现在还没有前端,所以使用 postman 来测试接口好不好用:

javascript - 练习题:AJAX用户登录(nodejs服务响应)_node.js_02

使用,红、黄、蓝、绿、黑的箭头顺序依次:

红:选择 POST 发送请求;

黄:输入新建的web服务地址;

蓝:选请求体 body , JSON ;

绿:输入 json 格式的数据;

黑:发送请求;

最后得到 “登录成功!” 的返回结果;

也可以只写 用户名或密码,或错误的数据来反复测试接口可用性,这个简易的接口目前没问题;


前端编码

先写个 login.html 页面;

<div class="content">
<div class="login">
<form id="login-form" action="" method="GET">
<div class="inputs">
<label for="">用户</label>
<input type="text" id="username" placeholder="请输入用户名" required>
<div class="text-err">
<div class="text-msg"></div>
<div class="triangle"></div>
</div>
</div>
<div class="inputs">
<label for="">密码</label>
<input type="password" id="password" placeholder="请输入密码" required>
<div class="pass-err">
<div class="pass-msg"></div>
<div class="triangel"></div>
</div>
</div>
<button type="button" id="submit">登录</button>
</form>
</div>
</div>
<script src="login.js"></script>

只包括一个表单和一个引入的js文件,我们的重点就在 login.js 文件;

login.html 页面长这样:

javascript - 练习题:AJAX用户登录(nodejs服务响应)_ajax_03

我们将通过 login.js 的前端代码来实现与后端服务交互;

面对过程:新手写法;

let submitBtn = document.querySelector("#submit");
submitBtn.addEventListener('click', function () {
let username = document.querySelector("#username").value;
let password = document.querySelector("#password").value;
login(username, password);
});

function login(username, password) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
console.log(xhr.responseText);
} else {
alert('请求失败');
}
}
}
xhr.open("POST", "http://localhost:2999/user/login");
xhr.setRequestHeader('Content-Type', 'application/json'); // 请求头
xhr.send(JSON.stringify({ username: username, password: password }));
}

面向对象:工程师写法;

var LoginObj = {
init() { // 初始化
let submitBtn = document.querySelector("#submit");
submitBtn.addEventListener('click', () => { // 绑定事件,箭头函数
let username = document.querySelector("#username").value;
let password = document.querySelector("#password").value;
if (username && password) {
this.sendLoginRequest(username, password); // this指向 LoginObj
} else {
alert("账号或密码不能为空");
}
});
},
sendLoginRequest(username, password) { // 发送请求
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () { // 事件监听
if (xhr.readyState == 4) {
if (xhr.status == 200) {
// 拿到后端数据
console.log(xhr.responseText);
// 跳转 location'
location.href = "./index.html";
} else {
alert('请求失败');
}
}
}
xhr.open("POST", "http://localhost:2999/user/login");
xhr.setRequestHeader('Content-Type', 'application/json'); // 请求头 json 类型
xhr.send(JSON.stringify({ username: username, password: password }));
}
}

面向对象,还可以封装公共请求:高手写法;

var LoginObj = {
init() { // 初始化
let submitBtn = document.querySelector("#submit");
submitBtn.addEventListener('click', () => {
let username = document.querySelector("#username").value;
let password = document.querySelector("#password").value;
if (username && password) {
this.sendLoginRequest(username, password);
} else {
alert("账号或密码不能为空");
}
});
},
sendLoginRequest(username, password) { // 发送请求
var xhr = createXMLHttp();
xhr.sendRequest({
method: "POST",
url: "http://localhost:2999/user/login",
jsonData: { username: username, password: password },
sucCallback: function () {
console.log(xhr.responseText);
location.href = "./index.html";
},
errCallback: function () {
alert('请求失败,请联系管理员');
}
});
}
}

// 封装公共请求,使用了闭包,看起来高大上了;
function createXMLHttp() {
var xhr = new XMLHttpRequest();
return {
// 把可变的属性抽出来;
// method -- post
// url -- 地址;
// jsonData -- 请求数据
// sucCallback -- 成功回调
// errCallback -- 失败回调
sendRequest({ method, url, jsonData, sucCallback, errCallback }) {
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
sucCallback();
} else {
errCallback();
}
}
}
xhr.open(method, url);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(jsonData));
}
}
}

window.onload = function () {
LoginObj.init();
}

测试结果:

只输入用户名:账户或密码不能空;

错误的用户名和密码:请求失败,请联系管理员;

正确的用户名和密码:就直接跳转 index.html ;