服务器渲染+自定义模块+mysql操作

1.服务器渲染

A.第一步,导入模块库和第三方库

npm init

npm --registry https://registry.npmmirror.com install art-template moment

B.第二步,调整html文件

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>仿服务器资源</title>
  </head>
  <body>
    <div class="container" style="width: 600px; margin: 0 auto">
      <h1>Index Of-2</h1>
      <table
        border="1"
        width="600px"
        style="border-spacing: 0; text-align: center"
      >
        <thead>
          <th>图片</th>
          <th>文件名称</th>
          <th>最后更改时间</th>
          <th>大小(字节)</th>
          <th>文件类型</th>
        </thead>
        <tbody id="tShow">
          {{each data}}
          <tr>
            {{if $value.type == 'F'}}
            <td>
              <img src="./imgs/file.png" width="50" alt="" />
            </td>
            {{else }}
            <td>
              <img src="./imgs/folder.png" width="50" alt="" />
            </td>
            {{/if}}
            <td>{{$value.uname}}</td>
            <td>{{$value.mtime}}</td>
            <td>{{$value.size}}</td>
            <td>{{$value.type=='F'?'文件':'文件夹'}}</td>
          </tr>
          {{/each}}
        </tbody>
      </table>
    </div>
  </body>
  <script></script>
</html>

调整js文件

var http = require("http");
var fs = require("fs");
var moment = require("moment");
var template = require("art-template"); // 第三方模块,读取数据的
template.defaults.root = "./"; // 设置文件读取路径为相对路径!!!!

var server = http.createServer();

server.on("request", function (req, res) {
  // 防止乱码
  res.setHeader("Content-Type", "text/html;charset=utf-8");
  var ulrs = req.url;
  // 普通html文档
  if (req.url == "/") {
    fs.readdir("./", "utf8", function (err, data) {
      console.log(data, "datadir");
      var data_arr = []; // 返回的结果
      var count = 0; // 计数
      for (var i = 0; i < data.length; i++) {
        data_arr[i] = {};
        // 异步,闭包
        (function (i) {
          fs.stat(data[i], function (err1, data1) {
            // 数量叠加
            count++;
            // 判断是否为文件
            if (data1.isFile()) {
              data_arr[i].type = "F";
            } else {
              data_arr[i].type = "NF";
            }
            data_arr[i].uname = data[i];
            // 为了读取时间更友好,采用第三方模块
            data_arr[i].mtime = moment(data1.mtime).format(
              "YYYY-MM-DD HH:mm:ss"
            );
            data_arr[i].size = data1.size;
            // 跳出闭包,并返回值
            if (count == data.length) {
              res.end(template("./01index.html", { data: data_arr }));
            }
          });
        })(i);
      }
    });
  } else {
    // 其他资源
    fs.readFile("." + ulrs, function (err, data) {
      res.end(data);
    });
  }
});

// 端口
server.listen(5657, function () {
  console.log("端口5657已启动,正在加载......");
});

效果图:
在这里插入图片描述

2.node模块化及commonJS规范

2.1 node模块化

通过前面几个章节的学习,我们基本掌握了NodeJS编程的基础知识,但是我们也直观的发现了一个问题,和我们之前学习浏览器编程时JS,差异还是很大的;都是JS编程,为何有这种差异?前面写过的仿Apache服务器的案例中,使用过内置fs模块,使用过moment模块,而这些模块都不是我们写的,都是直接拿过来使用,那么我们能不能自己写一个模块,应该怎么写,有那些规矩,如果我们自己写了一个模块,能不能提供给其他编程人员直接使用,应该如何使用?
在这里插入图片描述

2.2 commonJS规范的由来

JS的表现能力取决于宿主环境提供的API,在web1.0时代。W3C组织提供了浏览器的规范支持,在Web2.0时代。随着HTML5的发展,更多的标准API出现在了浏览器中,但是,在后端JS中标准的指定纹丝不动;

由火狐工程司Kevin Dangoor于2009年1月提出名为ServerJS的规范;2009年8月,更名为CommonJS,以显示API的更广泛实用性。

引用:

我在这里描述的不是技术问题。这是一个人闷聚在一起并决定前进并开始建立更大和更冷的东西的问题。——Kevin Dangoor
在这里插入图片描述

2.3 CommonJS的模块规范

CommonJS对模块的定义十分简单,主要分为:

A. 模块引用

使用require()方法引用一个模块API

B. 模块定义

在模块中使用exports对象导出当前模块数据或方法;

在模块中还存在一个module对象,它代表模块自身,module对象由一个exports属性,用于数据导出;

其实exports对象就是modele.exports的引用:exports===module.exports

C. 模块标识

其实就是模块的文件名,必须符合小驼峰法命名规则,使用require()引入时使用**.或…开头的相对路径或绝对路径**,引入时可以不写文件后缀名;

重点注意:模块中的方法和变量的作用于尽在模块内部,每个模块具有独立的空间,互不干扰。

CommonJS构建的模块机制中的引入与导出是我们完全不用考虑变量污染或者替换的问题,相比与命名空间的机制,简直就是天才和菜鸟的区别;

2.3.1 自定义模块

1.自定义模块(1.a.js)

var a=1;
var b=2;
var c=a+b;
exports.data=c;

2.加载(2.b.js)

var a=require("./1.a");//自定义模块不需要写后缀名,第二,要用相对路径写法
console.log(a);
2.3.1.1 默认导出与默认导入

A. 默认导出语法export.default默认导出的成员

B. 默认导入语法import接收名称 from ‘模块标识符’

定义2.m1.js

//定义私有成员a和c
let a=10;
let c=20;

//外界访问不到d,因为它没有暴露出去
let d=30;

function show(){}

//将本模块中的私有成员暴露出去,供其他模块使用
export default{
    a,c,show
}

导入模块成员2.index.js

//导入模块成员
import m1 from './2.m1.js'  //加后缀名
console.log(m1)

//在这里使用会报错,要配置package.json的文件,"type":"module"

输出结果在这里插入图片描述
注意:每个模块中,只能使用唯一的一次export default,否则会报错

2.3.1.2 按需导出与按需导入

A. 按需导出语法 export let s1=10;

B. 按需导入语法 import{s1} from ‘模块标识符’

注意:每个模块中,可以使用多次按需导出

m1.js

//定义私有成员a和c
let a=10;
let c=20;

//外界访问不到d,因为它没有暴露出去
let d=30;

function show(){}

//将本模块中的私有成员暴露出去,供其他模块使用
export default{
    a,c,show
}

//按需导出
export let s1='aaa';
export let s2='ccc';
export function say(){
    console.log('hello world')
}

index.js

//导入模块成员
import m1 from './2.m1.js'  //加后缀名
console.log(m1)

//在这里使用会报错,要配置package.json的文件,"type":"module"

//按需导入,其中名字必须和按需导出的名字一致
import { s1, s2, say as saySay } from './2.m1.js'
console.log(s1, s2);
//如果一旦更改的名字,就只能用新名字,不可以使用原来的名字了
console.log(saySay)
//console.log(say)  //say is not defined 
2.3.1.3 直接导入并执行模块代码

有时候,我们只想单纯执行某个模块中的代码,并不需要得到模块中向外暴露的成员,此时,可以直接导入并执行模块代码

//当前模块

//在当前模块循环输出一些东西
for(var  i=0;i<3;i++){
    console.log('你真棒');
}

//导入模块

import './2.m1.js'

2.4 模块加载的顺序和规则

在CommonJS规范中,使用require()加载(引入)模块时,模块标识必须使用相对路径或绝对路径指明模块位置,但是在node的实现中,我们可以不知名模块路径;如:require(‘fs’)、require(‘moment’);

如果没有指明路径,那就是加载核心模块或第三方模块,指明加载路径一般就是加载自定义模块;

不管加载什么模块,都是优先从缓存中加载:

说明:

​ Node加载模块时,如果这个模块已经被加载过了,则会直接缓存起来,将来再次引用 是不会再次加载这个模块(即:如果一个模块被加载两次,则模块中的代码只会被执行 一次)。

而核心模块和第三方模块的加载顺序就是:

说明:

​ 先加载核心模块,核心模块的内容都是在安装node时已经编译好的可执行的二进制代码,加载执行的速度,仅次于缓存加载,如果核心模块中没有,则加载第三方模块。

第三方模块加载的规则:

说明:

​ A. 先在当前文件的模块所属目录去找node_modeules目录

​ B. 如果找到,则去该目录中找模块名的目录,如:moment

​ C. 如果找到moment目录,则找该目录中的package.json文件

​ D. 如果找到package.json文件,则找该文件中的main属性

​ E. 如果找到main属性,则拿到该属性对应的文件

​ F. 如果找到moment目录之后

​ \1. 没有package.json

​ \2. 或者由package.json没有main属性

​ \3. 或者由main属性,但是指向的路径不存在

​ \4. 则node会默认去看一下moment目录中有没有index.js–>index.json–>index.node文件

​ G. 如果找不到index或者找不到moment或者找不到node_modules

​ H. 则进入上一级目录找node_moudles查找(规则同上)

​ I. 如果上一级还找不到,继续向上,一致到当前文件所属磁盘的根目录

​ J. 如果到磁盘根目录还没有找到,直接报错

3.mysql的增删改查

3.1 表结构

在这里插入图片描述

3.2 新建项目搭建环境

npm init
npm install mysql moment art-template jquery bootstrap formidable --registry https://registry.npmmirror.com install express

html界面(03studentManage.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生信息</title>
    <link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css" />
</head>
<body>
    <div class="container">
        <h1>学生信息管理界面</h1>
        <table class="table">
            <tr>
                <th>学号</th>
                <th>姓名</th>
                <th>年龄</th>
                <th>性别</th>
                <th>登录名</th>
                <th>登录密码</th>
            </tr>
            {{each datas}}
            <tr>
                <td>{{$value.Sno}}</td>
                <td>{{$value.Sname}}</td>
                <td>{{$value.Sage}}</td>
                <td>{{$value.Ssex}}</td>
                <td>{{$value.loginName}}</td>
                <td>{{$value.loginPwd}}</td>
            </tr>
            {{/each}}
        </table>
    </div>
</body>
</html>

响应js(03studentManage.js)

//导入模块
var http = require('http');//核心模块,
var fs = require('fs');//核心模块
var moment = require('moment');//第三方模块
var template = require('art-template');
template.defaults.root = './';
var db = require('./3.studentDB');
var server = http.createServer();

//响应
server.on('request', function (request, response) {
    var urls = request.url;
    //防止乱码
    response.setHeader('Content-type', "charset=utf-8");
    //资源绑定
    if (urls == "/") {//html资源
        response.end(template('3.studentManage.html', { datas: db.datas }));
    } else {
        response.setHeader('Content-type', "text/css;charset=utf-8");
        //读取其他资源
        fs.readFile('.' + urls, function (err, data) {
            response.end(data);
        })
    }
});

//端口号
server.listen(2323, function () {
    console.log('服务2323正在启动.....');
});

注意:资源绑定时,bootstrap样式文件要作为其他资源进行绑定,否则样式会不生效

连接数据库(03studentDB.js)

//数据库操作
var mysql = require('mysql');
//连接数据库
var connection = mysql.createConnection({
    host: "localhost",
    user: "root",
    password: '123456',
    database: "school2"
});

//打开桥梁
connection.connect();
var sql = "select * from student";
connection.query(sql, function (err, data) {
    module.exports.datas = data;
});

//关闭桥梁
connection.end();

4.连接mysql的增删查改

4.1 表结构

在这里插入图片描述

4.2 端口

//端口页面
const http=require('http');
const yewu=require('./2.yewu');

const server=http.createServer();
//事件
yewu.bind(server);

//端口
server.listen(9000,function (){
    console.log('正在启动服务9000.....')
})

4.3 业务界面

//业务界面
var fs = require('fs');
var url = require('url');//地址对象
var template = require('art-template');
var moment = require('moment');
template.defaults.root = './';//相对路径
var db = require('./3.db');//连接数据库的,自定义模块
var formidable = require('formidable');//读取表单

//方法
module.exports.bind = function (server) {
    //读取数据
    server.on('request', function (request, response) {
        //获取对象
        var urlS = url.parse(request.url, true);
        //1.查询
        if (urlS.pathname == '/') {
            let tSname = urlS.query.tSname == undefined ? "" : urlS.query.tSname;
            db.student_selectBySname(tSname, function (data) {
                response.end(template("./4.index.html", { datas: data }));
            });
        }
        //2.删除
        else if (urlS.pathname == '/delete') {
            let sno = urlS.query.sno == undefined ? "" : urlS.query.sno;
            db.student_deleteBySno(sno, function (data) {
                response.setHeader('Content-type', 'text/html;charset=utf-8');
                var result = "<script>alert('删除失败');window.location.href='http://localhost:9000';</script>";
                if (data.affectedRows > 0) {
                    result = "<script>alert('删除成功');window.location.href='http://localhost:9000';</script>"
                }
                response.end(result);
            });
        }
        //3.查看
        else if (urlS.pathname == '/see') {
            if (request.method.toString() == "GET") {//提交方式
                let sno = urlS.query.sno == undefined ? "" : urlS.query.sno;
                db.student_selectBySno(sno, function (data) {
                    if (sno == "") {
                        var obj = new Object();
                        obj.Sno = "";
                        obj.Sname = "";
                        obj.Sage = "";
                        obj.Ssex = "";
                        obj.loginName = "";
                        obj.loginPwd = "";
                        response.end(template('5.see.html', { datas: obj }));
                    } else {
                        response.end(template('5.see.html', { datas: data[0] }));
                    }
                });
            }
            else if (request.method.toString() == "POST") {
                let sno = urlS.query.sno == undefined ? "" : urlS.query.sno;
                var formData=new formidable.IncomingForm();//可以获取表单提交的所有数据
                formData.parse(request,function (err,data){
                    //调用数据库
                    db.student_addAndUpdate(sno,data,function (data1){
                        response.setHeader('Content-type', 'text/html;charset=utf-8');
                        var result = "<script>alert('修改失败');window.location.href='http://localhost:9000';</script>";
                        if (data1.affectedRows > 0) {
                            result = "<script>alert('修改成功');window.location.href='http://localhost:9000';</script>"
                        }
                        response.end(result);
                    })
                });
            }
        }
        else {
            //其他资源
            fs.readFile("." + request.url, function (err, data) {
                response.end(data);
            })
        }
    });
}

4.4 db界面

//连接数据库的
const mysql = require('mysql');

//创建对象
var connection = mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: '123456',
    database: 'school27'
});

//打开
connection.connect();

//查询,根据用户名进行模糊查询
module.exports.student_selectBySname = function (sname, callback) {
    let sql = `select * from student where sname like '%${sname}%'`;
    connection.query(sql, function (err, data) {
        if (!err) {
            callback(data);
        }
    });
}

//删除,根据学号删除
module.exports.student_deleteBySno = function (sno, callback) {
    let sql = `delete from student where sno=${sno}`;
    connection.query(sql, function (err, data) {
        if (!err) {
            callback(data);
        }
    });
}

//根据学号查看学生信息
module.exports.student_selectBySno = function (sno, callback) {
    let sql = `select * from student where Sno='${sno}'`;
    connection.query(sql, function (err, data) {
        if (!err) {
            callback(data);
        }
    });
}

//新增或者修改
module.exports.student_addAndUpdate = function (sno, student, callback) {
    let sql = `insert into student values('${student.tSno}','${student.tSname}',${student.tSage},'${student.tSsex}','${student.tLoginName}','${student.tLoginPwd}')`;
    if (sno !== "") {
        sql = `update student set Sno='${student.tSno}',Sname='${student.tSname}',Sage=${student.tSage},Ssex='${student.tSsex}',loginName='${student.tLoginName}',loginPwd='${student.tLoginPwd}' where Sno='${sno}'`;
    }
    connection.query(sql, function (err, data) {
        if (!err) {
            callback(data);
        }
    });
}

4.5 html页面

4.index.html查看界面

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>学生信息管理</title>
    <link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css" />
</head>

<body>
    <div class="container">
        <form action="./">
            <h1>学生信息管理-完整</h1>
            用户名:<input type="text" name="tSname" class="form-control" style="width: 200px;display: inline-block;">
            <input type="submit" value="搜 索" class="btn btn-info">
            <a href="./see" class="btn btn-danger">新增</a>
            <table class="table">
                <tr>
                    <th>学号</th>
                    <th>姓名</th>
                    <th>年龄</th>
                    <th>性别</th>
                    <th>登录名</th>
                    <th>登录密码</th>
                    <th>操作</th>
                </tr>
                {{each datas}}
                <tr>
                    <td>{{$value.Sno}}</td>
                    <td>{{$value.Sname}}</td>
                    <td>{{$value.Sage}}</td>
                    <td>{{$value.Ssex}}</td>
                    <td>{{$value.loginName}}</td>
                    <td>{{$value.loginPwd}}</td>
                    <td>
                        <a href="./see?sno={{$value.Sno}}" class="btn btn-info">查看</a>
                        <a href="javascript:if(confirm('确定要删除吗?')){window.location.href='./delete?sno={{$value.Sno}}'}"
                            class="btn btn-danger">删除</a>
                    </td>
                </tr>
                {{/each}}
            </table>
        </form>
    </div>
</body>

</html>

5.see.html(新增界面)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>查看详情</title>
    <link rel="stylesheet" href="./node_modules/bootstrap/dist/css/bootstrap.min.css" />
</head>

<body>
    <div class="container">
        <form action="./see?sno={{datas.Sno}}" method="post">
            <table>
                <tr>
                    <td>学号:</td>
                    <td><input type="text" name="tSno" class="form-control" value="{{datas.Sno}}"></td>
                </tr>
                <tr>
                    <td>姓名:</td>
                    <td><input type="text" name="tSname" class="form-control" value="{{datas.Sname}}"></td>
                </tr>
                <tr>
                    <td>年龄:</td>
                    <td><input type="text" name="tSage" class="form-control" value="{{datas.Sage}}"></td>
                </tr>
                <tr>
                    <td>性别:</td>
                    <td><input type="text" name="tSsex" class="form-control" value="{{datas.Ssex}}"></td>
                </tr>
                <tr>
                    <td>登录名:</td>
                    <td><input type="text" name="tLoginName" class="form-control" value="{{datas.loginName}}"></td>
                </tr>
                <tr>
                    <td>登录密码:</td>
                    <td><input type="text" name="tLoginPwd" class="form-control" value="{{datas.loginPwd}}"></td>
                </tr>
                <tr>
                    <td colspan="2">
                        <input type="submit" value="确 定" class="btn btn-info">
                    </td>
                </tr>
            </table>
        </form>
    </div>
</body>

</html>

如果上述跳转路由报错或者一直在加载,可检查sql语句是否正确
在这里插入图片描述
在这里插入图片描述

5.Express

5.1 简介

Express是基于node.js平台,快速、开放、极简的Web开发框架,提供一系列强大大特性帮助你创建各种Web应用。Express不对node.js已有的特性进行二次抽象,我们只是在它之上扩展了Web应用所需的功能。丰富的HTTP工具以及来自connect框架的中间件随取随用,创建强健、友好的API变得快速又简单

WEB引用程序

Express是一个保持最小规模的灵活的Node.js Web应用程序开发框架,为Web和移动应用程序提供一组强大的功能

API

使用你所选择的各种HTTP使用工具和中间件,快速方便地创建强大的API

性能

Express提供精简的基本Web应用程序功能,而不会隐藏您了解和青睐的node.js功能。

框架

许多流行的开发框架都基于Express构建

5.2 安装express

npm install express

5.3 express基本用法

var express = require("express");

var app = express();

app.get("/", function (req, res) {
  res.send("hello world");
});

app.get("/see", function (req, res) {
  console.log(req);
  res.send("你真棒");
});

app.listen(8888, function () {
  console.log("请求访问8888......");
});
  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值