express
Express
一、服务端网页编程
1、什么是一个web服务器
前面已经记录,看笔记,如果不太好记得再来整理一下
什么是 web 服务器? - 学习 Web 开发 | MDN (mozilla.org)
2、建立一个网站需要的软件
3、如何将文件上传到web服务器
SFTP:将pc端文件上传到服务器 eg:FileZilla
Rsync:Unix系统 命令行使用rsync 一种本地到远程的文件同步工具
GitHub:允许通过Github Pages发布网站
其它:
Web界面:作为远程文件上传服务前端的HTML界面,由自己的托管服务提供
WebDAV:不了解
4、服务端简介
。。。
使用js和Nodejs进行服务端网页的编程 如果使用python的话就是Django框架
Node
开源、跨平台的运行时环境
可以直接运行于计算机或者服务器os上
省略了一些浏览器专用的API,添加了对OS API的支持(例如HTTP库或者文件系统库)
可以使用nodejs的HTTP包创建一个简单的web服务器
Express
是Node框架,是其它流行框架的底层库
设置Node开发环境
安装了Node和npm之后才可以使用Express
测试是否安装成功
C:\Users\邹阳>node -v
v16.16.0
C:\Users\邹阳>npm -v
8.11.0
创建一个基础纯Node服务器
创建一份hellonode.js代码
在代码所在位置的命令行输入 node hellonode.js
访问返回的URL 浏览器回显示出js中设置好的字符
NPM
创建一个目录且进入myapp
使用init命令
该命令会为应用创建一个package.json文件,且该命令会请求一系列信息——包名、版本等 程序初始进入点的文件名index.js
查看package.json
{ "name": "myapp", "version": "1.0.0", "description": "这是一个学习npm的package", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "", "license": "ISC" }
在myapp中安装express
npm install express
package.json文件中会出现dependencies依赖包
调用require()使用库
const express = require("express"); const app = express(); app.get("/", (req, res) => { res.send("Hello World!"); }); app.listen(8000, () => { console.log("示例程序正在监听 8000 端口!"); });
注意:这里文件名要保存为index.js
启动服务器
node index.js
安装Express应用生成器
功能:生成express应用的框架
npm install express-generator -g
加上-g就是全局生成 对于所有应用都可以使用
进入应用目录,运行以下命令,即可创建一个名为 “helloworld” 的 Express 应用
express helloworld
ps:express会在当前目录的子目录创建新的应用,控制台可以看到构建的构成
cd helloworld
npm install
安装所有依赖
SET DEBUG=helloworld:* & npm start
运行应用:DEBUG可以展示应用运行时返回的有用的日志信息
http://127.0.0.1:3000/
访问浏览器URL
Express教程
本地图书馆网站
创建站点框架
一、知识点
cmd powerShell bash三者之间的区别
cmd、bash、powershell_cmd和bash_我脾气很好的博客-CSDN博客
linux的bash要比cmd强大很多
安装express生成器
Linux版本:sudo npm install express-generator -g
windows版本:npm install express-generator -g
运行express
express
默认使用:Jade视图引擎+CSS
-v, --view <engine> 添加 <engine> 视图引擎支持
挑选视图引擎时需要考虑的内容很多,详情可以见MDN的链接
Express 教程 2:创建站点框架 - 学习 Web 开发 | MDN (mozilla.org)
本项目使用Pug模板引擎
-c, --css <engine> 添加 <engine> 样式表引擎支持 (less|stylus|compass|sass) (默认为纯 css)
上述命令可以选择CSS引擎(不是必须,不做要求)
数据库
express不提供数据库管理机制,可以使用Node支持的所有数据库
二、实现步骤
先在D盘安装生成器
npm install express-generator -g
然后在D盘中生成应用express-locallibrary-tutorial 确定视图引擎为Pug
express express-locallibrary-tutorial -v pug
在应用目录下安装依赖
npm install
运行应用
Linux版本:DEBUG=express-locallibrary-tutorial:* npm start
windows版本:SET DEBUG=express-locallibrary-tutorial:* & npm start
ps:npm start也可以启动命令,但是不会看到调试信息
浏览器中查看
http://localhost:3000/
一个Express应用就配置成功,托管于localhost:3000
因为文件改动时要重启服务器才能看到网站的改动,手动启停服务器麻烦,所以需要自动化
nodemon是一个最简便的自动化工具之一(通常全局安装)
npm install -g nodemon
还可以选择作为开发依赖安装在本地,使用这个项目的开发人员只要安装应用就可以自动获取
npm install --save-dev nodemon
ps:
这里解释一下npm install -s -g -d之间的区别
npm install -s
npm install XXX -s相当于npm install -S相当于 npm install –save
局部安装 表示生产环境下的依赖 如果依赖在项目中起作用的话,就需要-s安装
npm install -d
局部安装 表示开发环境下的依赖 如果项目上线后库就没用了,使用-d安装(例如webpack部署打包、babel解析代码等)
npm install -g
全局安装,安装过一次之后,可以直接使用
npm install
与npm install -s一样
全局安装完成之后的使用 nodemon来代替node即可
如果是局部安装那么需要按照MDN中的脚本操作
应用文档目录
/express-locallibrary-tutorial
app.js:真实的应用入口 设置并返回express应用对象
/bin
www:js文件 调用应用入口的启动脚本(通过require app来启动) 还设置了一些应用的错误处理,加载 app.js 来完成其余工作
package.json:定义依赖项和其它信息
/node_modules
[约 4,500 个子文件夹和文件]
/public
/images
/javascripts
/stylesheets
style.css
/routes :用不同模块保存应用路由
index.js
users.js
/views:保存模板
error.pug
index.pug
layout.pug
突然发现之前没有pug 所以需要手动安装一下
npm install pug
ps:
require()是一个全局的node函数,可以将模块导入到当前文件。
app.js文件:
1、使用 require()
导入了一些实用 node 库,其中包括之前用 NPM 下载的 express
、http-errors
、morgan
和 *cookie-parser
*,还有一个 path
库,它是用于解析文件和目录的核心 node 库。
2、然后 require()
的是用户路由目录中的模块。
3、用导入的 express
模块来创建 app
对象,然后使用它来设置视图(模板)引擎。
设置视图(模板)引擎
a、view
app.set("views", path.join(__dirname, "views"));
指定模板的存储文件夹
b、view engine
app.set("view engine", "pug");
指定模板库
4、app.use()
调用将中间件库添加进请求处理链。
5、所有中间件都已设置完毕后,现在把(之前导入的)路由处理器添加到请求处理链中。
6、最后一个中间件为错误和 HTTP 404 响应添加处理方法。
7、添加到exports模块,使其可以通过bin/www导入
module.exports = app;
ps:windows删除文件夹
rmdir /s FileName
npm查看已安装的包(全局、本地)
npm ls/npm -g ls
- MDN上最后还有一个挑战自我,我增加了一个users文件夹然后将cool.js文件放置在了里面,在app.js中增加了该路由中间件但是好像路径这里设置有问题,目前还没有讲到,之后来填坑
使用数据库Mongoose
与数据库交互的方式
数据库的原生查询语句 SQL等
使用对象数据模型ODM或对象关系模型ORM(推荐)
它们能够将网站中的数据表示为js对象,然后将他们映射到底层数据库
优缺点:原始查询语句的性能高,ODM或者ORM可以用js对象的思维而不用转向数据库语义的思维,可以更方便地对数据进行验证和检查。
ODM -> Mongoose:为异步工作环境设计的MongoDB对象建模工具(MongoDB 数据库里,“集合”中的“文档” 类似于 关系数据库里“表”中的“行”。
MongoDB 文档:https://mongoosejs.com/docs/guide.html
前面涉及到的连接数据库等在数据库那篇博文中
定义library模式
为每个模型创建单独的文件
/express-locallibrary-tutorial // 项目根目录
/models
author.js
book.js
bookinstance.js
genre.js
作者模型
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const AuthorSchema = new Schema({
first_name: { type: String, required: true, max: 100 },
family_name: { type: String, required: true, max: 100 },
date_of_birth: { type: Date },
date_of_death: { type: Date },
});
// 虚拟属性'name':表示作者全名
AuthorSchema.virtual("name").get(function () {
return this.family_name + ", " + this.first_name;
});
// 虚拟属性'lifespan':作者寿命
AuthorSchema.virtual("lifespan").get(function () {
return (
this.date_of_death.getYear() - this.date_of_birth.getYear()
).toString();
});
// 虚拟属性'url':作者 URL
AuthorSchema.virtual("url").get(function () {
return "/catalog/author/" + this._id;
});
// 导出 Author 模型
module.exports = mongoose.model("Author", AuthorSchema);
路由和控制器
现在模型已经创建好了,现在要创建的主要是:
- 路由
- 控制器:获取到数据,创建一个HTML页面显示出数据,并将页面返回给用户,以便在浏览器中查看
- 视图
路由入门
将所有与图书有关的路由保存在catalog模块中,在添加处理账户或者其它功能的路由时,可以分开保存。
1、需要在routes文件夹中添加路由模块
2、在app.js中添加该路由模块require然后使用use
路由函数
router.get("/about", (req, res) => {
res.send("关于此维基");
});
Router.get()
方法定义的“about”路由(下方重现的)仅响应 HTTP GET 请求。第一个参数是 URL 路径,第二个参数是一个回调,在收到带有路径的 HTTP GET 请求将调用之。
该回调有三个参数(通常命名为:req
、res
、next
),分别是:HTTP 请求对象、HTTP 响应、中间件链中的下一个函数。
路径路由
路径可以是字符串或者字符串模式或者是正则表达式
路由参数
URL /book/create 会匹配 /book/:bookId 这样的路由(将提取值为'create' 的 'bookId')。
library所需路由
首页和列表页面没有包含任何额外的信息,因此它们返回的结果只取决于模型类型和数据库内容,创建和查询操作没有较大的变化
catalog/
:主页。catalog/<objects>/
:模型(藏书、藏书副本、藏书种类、作者)的完整列表(例如/catalog/books/
、/catalog/genres/
等)catalog/<object>/<id>
:具有_id
字段值的特定模型的详细信息页面(例如/catalog/book/584493c1f4887f06c0e67d37
)。catalog/<object>/create
:添加新模型的表单(例如/catalog/book/create
)。catalog/<object>/<id>/update
:更新具有_id
字段值的特定模型的表单(例如/catalog/book/584493c1f4887f06c0e67d37/update
)。catalog/<object>/<id>/delete
:删除具有_id
字段值的特定模型的表单(例如/catalog/book/584493c1f4887f06c0e67d37/delete
)。
而其他URL用于处理特定文档/模型实例的,会将目的标识嵌入URL(例如id),可以使用路径参数提取嵌入的信息,并传递给路由处理器
ps:有些命令只对bash有效,要在windows上使用bash,最简单的方法就是安装git 然后使用git bash here
总结一下上述的路由过程:1、需要有各自模块对应的模型(book.js)里面定义的是各种字段以及虚拟属性等
2、建立自己的route文件夹下的路由页面 将所有模块的路由都写入到了catalog.js文件下 但是各个路由对应的回调函数需要在controller层中写逻辑,因此新建了一个controller文件夹,在里面写各个模块的回调逻辑
3、最后在app.js中加入catalog.js路由中间件,将入口页面跳转到catalog/books路由指定页面
模板入门
本项目中使用pug作为模板,它主要用于编写html,语法干净且空格敏感,受haml影响很大。
pug:视图引擎
项目中在view文件夹下,在进行项目修改之前,需要先搞懂pug的语法
模板语法
每一行中的第一个单词是 HTML 元素,并且缩进用于指示嵌套元素。非嵌套元素(例如,各个段落)位于不同的行上。
元素属性被定义在其关联元素之后的括号中。属性键值对之间可以使用,或者空格间隔开
link(rel='stylesheet', href='/stylesheets/style.css')
所有属性的值都被转义(例如“>
”等字符转换为 HTML 代码等效项,如“>
”),以防止注入 JavaScript 或跨站点脚本攻击。
如果标记后跟着等号,则以下文本将被视为 JavaScript 表达式。
h1= title
p= 'Evaluated and escaped expression:' + title
如果标记后面没有等号,则将内容视为纯文本。还可以在行的开头使用管道‘|’字符来表示纯文本,允许您使用if
, else
, else if
和 unless
执行条件操作,使用each-in
或 while
语法执行循环/迭代操作。
ul
each val in [1, 2, 3, 4, 5]
li= val
语法还支持注释等,可以在链接中进行查看
Getting Started – Pug (pugjs.org)
学完了语法部分,因为页面有很多的commen部分,所以pug支持在基本模板上进行扩展
一般view/layout.pug就是基本模板
//- 基本模板 pug允许在基础模板上进行扩展 可以只替换每个页面不同的部分
doctype html
html
head
title= title
link(rel='stylesheet', href='/stylesheets/style.css')
body
//- 块标记 block用于标记“可在派生模板中替换的内容部分”
block content
如何使用基本模板
extends layout
block content
h1= title
p Welcome to #{title}
使用extends进行继承
接下来设计本地图书馆的基础模板(使用了Bootstrap的js和CSS)
修改部分:layout.pug基础模板+public/stylesheets/style.css
Bootstrap栅格系统,系统最多分为12列
主页设计
使用moment 来做日期格式化
moment是一个轻量级js日期库,用于解析、验证、操作和格式化日期