给自己的小商城建立简单后台的过程

使用到的工具

  • Node.js

    • Node.js既不是框架,也不是个语言,他是一个平台,可以运行JavaScript语言,没有 Dom、Bom
    • 模块作用域:也就是一个文件对应一个作用域
  • MongoDB

    • 非关系型数据库,跟Node.js是个不错的好基友
  • Mongoose

这里简单介绍,我会看一个新的板块去整理这些工具的知识

安装 Node 和 数据库 Mongo

  • Node.js

  • MongoDB

  • Mongoose

    • 在 cmd 中执行命令
    1
    npm install mongoose

建立 http 服务

简单的 http 服务

主要的逻辑是

  1. 创建http服务
  2. 监听request请求
  3. 监听端口,开启服务

新建xxx.js文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 最简单的服务搭建
var http = require("http");

// 1.创建服务
var server = http.createServer();

// 2. 监听服务
// 请求:处理
// 响应:一个请求对应一个响应,如果在一个请求的过程中,已经结束响应了,则不能重复发送响应

server.on("request", function (require, response) {
console.log("request");
});

// 3. 绑定端口号,启动服务
server.listen(3000, function () {
console.log("running");
});

发送和获取数据

我们最关心的问题应该有一下几点

  • 如何获取前台发送给后台的数据?

    • 通过req.on('data',function(){})
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    server.on("request", function(req, res) {
    req.on('data', function(chunk) {
    // console.log(chunk)

    // 接收过来的chunk就是前台发来的
    // 但是,chunk是二进制编码
    // JSON.parse() 方法用于将一个 JSON 字符串转换为对象。
    // 前台传数组也可以“
    // 但是前台如果直接传字符串的话就不能用json.parse了
    console.log(JSON.parse(chunk));
    }
    })
    • 如果前台发来的是字符串,那么可以通过chunk.toString()可以转化成人能看懂的字
    • 如果前台发来的是数据,对象等复杂数据类型的时候,那么可以JSON.parse(chunk)转化一下
  • 如何知道前台请求的是什么服务/功能?

    • 我们可以这么设计:在 url 中写下功能含义,比方说前台请求这个接口url:'http://127.0.0.1:3000/addUser',那我们直接获取addUser就可以了
    • 通过在监听服务里获取req.url即可知道前台请求的 url 后缀写的什么了,然后通过后缀写不同的功能
    1
    2
    3
    server.on("request", function (req, res) {
    console.log(req.url);
    });
  • 如何给前台发送数据

    • 可以通过res.write返回,只能返回BufferString
    • res.end()说明服务结束,如果不写他的话前台会收不到数据的
    • 如果想要返回复杂数据类型,比方说对象,数据,可以通过res.write(JSON.stringify(要返回的复杂数据))来返回数据
    1
    2
    3
    4
    5
    server.on("request", function (req, res) {
    // res.write('保存失败')
    res.write(JSON.stringify());
    res.end();
    });

我的整个设计如下

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
86
87
88
89
const http = require("http");
// 1. 创建服务

// 导入数据库
const User = require("./build_DB_Schema");
const server = http.createServer();

// 2. 监听request请求事件,设置请求处理函数
server.on("request", function (req, res) {
// 根据req.url 的同来分配不同任务
var url = req.url;
// ********************************
// 功能点1.添加用户
// ********************************
req.on("data", function (chunk) {
sendMsg = JSON.parse(chunk);

// 接收过来的chunk是二进制编码
// JSON.parse() 方法用于将一个 JSON 字符串转换为对象。
// 前台传数组也可以
// 但是前台如果直接传字符串的话就不能用json.parse了

// 功能一:添加用户
// 注释:在我添加用户之前需要价差数据中是否已经有了这个用户
// 如果检测有这个用户,我就不添加
// 如果检测没有这个用户,没有我就添加

if (url === "/wzq/addUser") {
User.find(sendMsg, function (err, ret) {
// 如果查询到的长度为0 ,代表数据库中没有数据
if (ret.length === 0) {
var newUser = new User({
userPhoneNumber: sendMsg.userPhoneNumber,
});
// 保存到数据库
newUser.save(function (err, ret) {
if (err) {
console.log("保存失败");
// 写给前台
res.write("保存失败");
res.end();
} else {
console.log("保存成功");
//
res.write("保存成功");
res.end();
}
});
} else {
console.log(`数据库中已经有${sendMsg.userPhoneNumber}这个用户`);
res.write(`数据库中已经有${sendMsg.userPhoneNumber}这个用户`);
res.end();
}
});
} else if (url === "/wzq/addHasBuy") {
// 功能点2:向指定用户中添加已经购买的商品
// 首先要找到,并且获取id
User.find(sendMsg, function (err, ret) {
let _id = ret[0]._id;
console.log("ret:", ret);

let oldArr = ret[0].userHasBuyShopes;
console.log(oldArr);

let newObj = {
userHasBuyShopes: oldArr,
};

// 更新
User.findByIdAndUpdate(_id, newObj, function (err, ret) {
if (err) {
console.log("更新失败");
} else {
console.log("更新成功");
}
});
});
}
});
// res.end 只支持字符串或者buffer
// 相应内容只能是二进制数据或者字符串
// 数字,对象,数组,布尔值都不行
// // res是必须要写的,不写的话前台收不到值
});

// 3. 监听端口,开启服务
server.listen("3000", function (argument) {
console.log("服务器已经开启run");
});

数据库操作

建立表结构

虽然Mongo是非关系型数据库,但是也是需要设计一下,不然咱增删改查也费劲啊

Mongo中有个叫架构Schema的东西,专门用来约束数据,其目的是:保证数据的完整性,减少脏数据

举个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 引入Schema
const Schema = mongoose.Schema;

// 建立博客的架构
var blogSchema = new Schema({
title: {
type: String,
required: true,
},
author: String,
body: String,
comments: [{ body: String, date: Date }],
date: { type: Date, default: Date.now },
hidden: Boolean,
meta: {
votes: Number,
favs: Number,
},
});

可以看到Schema规定了每条数据的架构,其中如果有不可缺少项,比如上面的title,可以通过required:true来约束

将架构发布为模型并挂载给外部

Q: 既然是模块作用域,那如何让模块与模块之间进行通信?
加载文件模块的目的更重要的是为了使用里面的成员

1
2
// 将架构发布为模型,并挂载,以便于外部使用
module.exports = mongoose.model("User", userSchema);

这里介绍一下module.exports,把所有需要被外部访问的成员挂在到 exports 上

比方说有两个文件,分别是a.jsb.js,如果想在a文件中使用b文件的内容,就需要把b文件暴露出来

1
2
3
4
5
6
// a.js

// 首先引入b.js 并给ret对象,这时候ret就可以使用b.js暴露出的方法了
// 这里的ret 随便起名
const ret = require("./b");
console.log(ret.add(5, 6)); // 11
1
2
3
4
5
//b.js
// 把 add 这个函数挂载
exports.add = function (a, b) {
return a + b;
};

问题

Q1:后台不能传递复杂数据类型给前台

1
2
3
4
5
6
7
8
// res.end 只支持字符串或者buffer
// 比方说我要返回 returnData ,我需要把他用JSON。stringify转换一下
// 相应内容只能是二进制数据或者字符串
// 数字,对象,数组,布尔值都不行
let returnData = { code: 1, data: ["你好"] };
res.write(JSON.stringify(returnData));
// res是必须要写的,不写的话前台收不到值
res.end();

Q2:敲代码的技巧:批量删除代码前面的 tab

shift + tab

Q3:提示 Cannot find module ‘mongoose’

安装 mongoose即可,这个插件是在运行的文件夹下的

就是说如果文件换了路径,也需要重新导入module

1
2
// 我用的是淘宝镜像,爽的
cnpm install mongoose