原生nodejs-搭建后端服务器,完成数据库的链接,客户端的访问,数据库表的操作,包含表单验证,Ajax通信

一、服务端

  • 1、搭建服务器

第一次搭服务器测试是否能成功运行

var http = require('http')
/* 加载model模块 */
var {
    
    
    createConnect,
    selectAll,
} = require('./model.js');

/* 获取的数据库内容 */
var connect;
http.createServer(async function (req, res) {
    
    
    if (!connect) connect = await createConnect();
    // 如果能输出就说明检测成功
    // console.log(connect);
    // 如果能输出就说明查询成功
    // console.log(await selectAll(connect));
    res.writeHead(200, {
    
    
        "Content-Type": "text/html;charset=utf-8",
        "Access-Control-Allow-Origin": "*" //CORS 允许谁跨域访问
    })
    res.end('服务器已经被我访问了');
}).listen(4001, "10.9.46.184", function () {
    
    
    console.log('服务器已开启');
})
  • 2、链接数据库

第一次改写数据库

/* 加载mysql插件 */
var mysql = require("mysql");
async function createConnect() {
    
    
    /* 创建连接池 */
    var pool = mysql.createPool({
    
    
        /* 配置文件 */
        "host": "localhost",
        /* 数据库默认的端口号 */
        "port": 3306,
        /* 数据库的名称 */
        "database": "game",
        /* 使用者 */
        "user": "root",
        /* 密码 */
        "password": "root"
    })
    /* 返回调用获取数据库里的数据内容 */
    return await getConnect(pool);
}
/* 创建链接池pool:因为是需要加载链接,那么就是要异步请求,这样的话考虑这个promise */
/* poll池子中有一个方法可以将池子里的数据拉出来 */
/* pool.getConnection回调函数是异步,所以说考虑这个promise */
function getConnect(pool) {
    
    
    return new Promise(function (resolve, reject) {
    
    
        /* 获取这个数据池里的数据给参数connect*/
        pool.getConnection(function (err, connect) {
    
    
            if (err) resolve(null);
            else resolve(connect);
        })
    })
}
/* 传入参数是得到的数据connect */
function selectAll(connect) {
    
    
    return new Promise(function (resolve, reject) {
    
    
        /* connect身上有一个query方法 */
        /* 传入的第一个参数是数据查询sql语句 */
        /* 第二个参数就是回调函数*/
        connect.query("SELECT * FROM `user` WHERE 1", function (err, result) {
    
    
            /* if查询失败就返回null */
            if (err) resolve(null)
            else resolve(result)
            /* 否则的话返回查询结果result */
        })
    })
}
/* 导出数据链接池 */
exports.createConnect = createConnect;
/* 导出所有查询结果 */
exports.selectAll = selectAll;

第一次通过index.html执行ajax发送请求测试服务器和数据库链接是否成功

init();

function init() {
    
    
   var xhr = new XMLHttpRequest();
   xhr.addEventListener("load", loadHandler);
   xhr.open("GET", "http://10.9.46.184:4001");
   xhr.send();

   function loadHandler(e) {
    
    
       console.log(xhr.response);
   }

}

二、客户端(未封装的singup功能完成)

1、完成表单验证

  1. 注册页面检测表单数据
    • 传入对应的name属性和value值,判断是否符合正则表达式
    • 根据表达式修改相应的css里的一项内容
    • 获取成功的表单数据对象
    • 对表单数据验证
var form,ids;
init();
function init(){
    
    
    form = document.querySelector('form')
    console.log(form);
    /* 给表单绑定提交事件和输入事件 */
    form.addEventListener("submit",submitHandler);
    form.addEventListener("input",inputHandler);

}
/* 提交事件 */
function submitHandler(e){
    
    
    e.preventDefault();
    /* 传入from对象,提出整个form表单数据对象 */
    var fd = new FormData(form);
    var obj={
    
    };
    /* 表单验证 */
    for(var [key,value] of fd){
    
    
        /* 遍历传入一个对象当中 */
        obj[key]=value;
        /* 对性别不做表单验证 */
        if(key==="sex")continue;
        /* 如果有数据不符合就聚焦到对应的元素上 */
        if(!judge(value,key)){
    
    
            document.querySelector("[name="+key+"]").focus();
            return;
        }
    }
}
/* 输入事件 */
function inputHandler(e){
    
    
    /* 节流函数 */
    if(e.target.type == "radio") return;
    if(ids) return;
    ids = setTimeout(function(){
    
    
        clearTimeout(ids);
        ids = undefined;
        // console.log(e.target.value);
        /* 验证数据的方法(表单的value,表单的name属性) */
        judge(e.target.value,e.target.name);
        
    },16)
    /*  */
}
/* 验证元素 */
function judge(value,name){
    
    
    if(regExpValue(value,name)){
    
    
        changeClass(name,["has-error","glyphicon-remove"],["has-success","glyphicon-ok"]);
        return true;
    }
    changeClass(name,["has-success","glyphicon-ok"],["has-error","glyphicon-remove"])
    return false;

}
/* 正则判断每一项是否合格 */
function regExpValue(value,name){
    
    
    switch(name){
    
    
        case "user":
            return /^\w{6,18}$/.test(value);
        case "password":
            return /^(?=\D+\d)(?=.*[a-z])(?=.*[A-Z])\w{8,16}$/.test(value);
        case "name":
            return /^[\u4e00-\u9fd5]{2,4}$/.test(value);
        case "age":
            return /^[0-9]$|^[1-9]\d$|^1[0-2]\d$/.test(value);
        case "tel":
            return /^1[3-9]\d{9}$/.test(value);
        case "email":
            return /^\w+\@\w+\.(com|org|net|cn|edu)(\.(cn|tw|hk))?$/.test(value);
    }
}

/* 改变css内容函数 */
function changeClass(name,removeClass,addClass){
    
    
    /* 获取当前的表单元素 */
    var input=document.querySelector("[name="+name+"]");
    /* 获取当前的表单元素父容器的classlist */
    var divlist=input.parentElement.classList;
    /* 获取当前的表单元素下一个兄弟元素的classlist */
    var spanlist=input.nextElementSibling.classList;
    if(divlist.contains(removeClass[0])) divlist.remove(removeClass[0]);
        divlist.add(addClass[0])
    if(spanlist.contains(removeClass[1]))spanlist.remove(removeClass[1]);
        spanlist.add(addClass[1])
}

在这里插入图片描述

function submitHandler(e){
    
    
    e.preventDefault();
    /* 传入from对象,提出整个form表单数据对象 */
    var fd = new FormData(form);
    console.log(fd);
    for(var [key,value] of fd){
    
    
        console.log(key,value);
    }
}

在这里插入图片描述

FormData(form)身上方法 作用
append 添加属性
set 设置某个属性(在formdtazhong 可以同时存在两个key)
get 获取这个属性设置的值
getALL 获取这个属性设置的所有值
keys 获取所有的key
value 获取所有的value

2、数据发送给服务器

  • 正确的获取了表单数据对象,通过Ajax向服务器传输数据
  • 传输成功服务端收到数据字符串转成对象
    此时的服务端代码就能争取的收取到传输上来的表单数据对象。
var http = require('http')
/* 加载model模块 */
var {
    
    
    createConnect,
    selectAll,
} = require('./model.js');

/* 获取的数据库内容 */
var connect;
http.createServer(async function (req, res) {
    
    
    if (!connect) connect = await createConnect();
    // 如果能输出就说明检测成功
    // console.log(connect);
    // 如果能输出就说明查询成功
    // console.log(await selectAll(connect));
    /* 接收到数据对象 */
    var data = await getData(req);
    console.log(data);
    res.writeHead(200, {
    
    
        "Content-Type": "text/html;charset=utf-8",
        "Access-Control-Allow-Origin": "*" //CORS 允许谁跨域访问
    })
    res.end(JSON.stringify({
    
    
        err: null,
        msg: "插入正确"
    }))
}).listen(4001, "10.9.46.184", function () {
    
    
    console.log('服务器已开启');
})

/* 接收客户端发来的数据函数 */
function getData(req) {
    
    
    /* 异步接收考虑promise */
    return new Promise(function (resolve, reject) {
    
    
        var data = "";
        /* req请求加载事件on,事件类型有data和end,回调函数里的参数就是收到的数据 */
        req.on("data", _chunk => data += _chunk);
        /* req数据接收完毕执行 */
        req.on("end", () => {
    
    
            try {
    
    
                /* 解析字符串成为对象 */
                data = JSON.parse(data);
            } catch (e) {
    
    };
            /* 返回出去这个数据对象 */
            resolve(data)
        });
    })
}

3、三种数据表的操作

/* 加载mysql插件 */
var mysql = require("mysql");
async function createConnect() {
    
    
    /* 创建连接池 */
    var pool = mysql.createPool({
    
    
        /* 配置文件 */
        "host": "localhost",
        /* 数据库默认的端口号 */
        "port": 3306,
        /* 数据库的名称 */
        "database": "game",
        /* 使用者 */
        "user": "root",
        /* 密码 */
        "password": "root"
    })
    /* 返回调用获取数据库里的数据内容 */
    return await getConnect(pool);
}
/* 创建链接池pool:因为是需要加载链接,那么就是要异步请求,这样的话考虑这个promise */
/* poll池子中有一个方法可以将池子里的数据拉出来 */
/* pool.getConnection回调函数是异步,所以说考虑这个promise */
function getConnect(pool) {
    
    
    return new Promise(function (resolve, reject) {
    
    
        /* 获取这个数据池里的数据给参数connect*/
        pool.getConnection(function (err, connect) {
    
    
            if (err) resolve(null);
            else resolve(connect);
        })
    })
}
/* 传入参数是得到的数据connect */
function selectAll(connect) {
    
    
    return new Promise(function (resolve, reject) {
    
    
        /* connect身上有一个query方法 */
        /* 传入的第一个参数是数据查询sql语句 */
        /* 第二个参数就是回调函数*/
        connect.query("SELECT * FROM `user` WHERE 1", function (err, result) {
    
    
            /* if查询失败就返回null */
            if (err) resolve(null)
            else resolve(result)
            /* 否则的话返回查询结果result */
        })
    })
}
/*传入参数是得到的数据connect和数组 得到的是插入后的结果  */
function insert(connect, arr) {
    
    
    return new Promise(function (resolve, reject) {
    
    
        /* 通过连接池的connect方法插入sql语句插入数据 */
        connect.query("INSERT INTO `user`(`user`, `password`, `name`, `sex`, `age`, `tel`, `email`) VALUES (?,?,?,?,?,?,?)", arr, function (err, result) {
    
    
            // console.log(err)
            if (err) resolve(null);
            else resolve(result);
        })
    })
}

/* 登录查询是否数据name和password同时相等 */
function login(connect, arr) {
    
    
    return new Promise(function (resolve, reject) {
    
    
        connect.query("SELECT * FROM `user` WHERE `user`=? AND `password`=?", arr, function (err, result) {
    
    
            if (err) resolve(null);
                /* 因为如果查询结果没查到,但是任然返回一个空数组,就会这样长度为0 */
            else if (result && result.length === 0) resolve(null);
            else resolve(result);
        })
    })
}
/* 导出数据链接池 */
exports.createConnect = createConnect;
/* 导出所有查询结果 */
exports.selectAll = selectAll;
/* 导出插入函数 */
exports.insert = insert;

以上就完成了一个未封装的注册类型的表单提交

猜你喜欢

转载自blog.csdn.net/m0_46672781/article/details/126184468