• 原生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('服务器已开启');
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    第一次通过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);
       }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    二、客户端(未封装的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])
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85

    在这里插入图片描述

    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);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    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)
            });
        })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    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;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74

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

  • 相关阅读:
    蓝桥杯 Java 括号序列
    leetcode406 根据身高重建队列
    基于NodeJs+MySQL+Vue的小区物业管理信息系统
    ECS框架浅析
    什么是RabbitMQ
    Mybatis-Plus入门实践
    行业追踪,2023-10-27
    不习惯的Vue3起步二 の alias别名、ref和reactive
    Redis的主从复制搭建
    【华为OD机试真题 python】竖直四子棋【2022 Q4 | 200分】
  • 原文地址:https://blog.csdn.net/m0_46672781/article/details/126184468