概述
一、模块化
模块化做为一种现代化的设计方法,这个概念最早起源于生产制造行业。如今这个概念已经被各行各业来衍生应用,在软件开发中也大量的采用了模块化思想。
所谓的模块化思想,将一个大程序按照功能划分为若干个小的模块,每个小程序模块完成一个特定的功能,所有的模块按某种方法组装起来,成为一个整体,完成整个系统所要求功能的程序设计方法。【推荐:node.js视频教程】
(一)、为什么需要模块化
为什么需要模块化:
程序复杂度上升代码越写越多,在一个文件里代码就会越来越长,不易维护。(把完成特定功能的代码分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少)
JavaScript 有复杂的依赖关系的时候就很容易出现一些变量的属性或方法被覆盖或改写,导致变量污染。这是因为js没有命名空间,不像其他语言通过命名空间可以有效的避免重名问题。
想要存在JavaScript 私有的变量
模块化思想解决问题:
可维护性:每个模块都是单独定义的,之间相互独立。模块尽可能的需要和外部撇清关系,方便我们独立的对其进行维护与改造。维护一个模块比在全局中修改逻辑判断要好的多。
命名冲突:为了避免在JavaScript中的全局污染,我们通过模块化的方式利用函数作用域来构建命名空间,避免命名冲突。
文件依赖:一个功能可能依赖一个或多个其他文件,使用是除了引入它本身还需要考虑依赖文件,通过模块化 我们只需要引入文件,无需考虑文件依赖(模块化可以帮助我们解决文件依赖问题)。
可复用性:虽然粘贴复制很简单,但是要考虑到我们之后的维护以及迭代。
(二)、什么是Nodejs模块
把具有公共功能的,抽离成一个单独的js文件作位一个模块。默认情况下,模块里的方法或属性,外面是访问不到的。如果想要在外面访问这些属性,方法,就必须在模块里通过exports
和module.exports
暴露,在需要使用的地方通过require()
进行引入。
//exports语法示例
// sum.js
exports.sum = function(a,b){
return a+b;
}
// main.js
var m = require("./sum");
var num = m.sum(10,20);
console.log(num);
//modules.exports语法示例
//sum.js
function sum(a,b){
return a+b;
}
module.exports= sum;
//main.js
var sum = require('./sum');
sum(10,20);// 30
登录后复制
CommonJS 规定:
每个模块内部,module 变量代表当前模块
module 变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口
加载某个模块,其实是加载该模块的 module.exports 属性。require() 方法用于加载模块。
(三)、nodejs中的模块分类与加载方式
Node.js 中根据模块来源的不同,将模块分为了 3 大类,分别是:
内置模块(内置模块是由 Node.js 官方提供的,例如 fs、path、http 等)
自定义模块(用户创建的每个 .js 文件,都是自定义模块)
第三方模块(包)(由第三方开发出来的模块,并非官方提供的内置模块,也不是用户创建的自定义模块,使用前需要先下载)
//1.加载内置模块不需要指定路径
var http = require('http');
//2.加载用户的自定义模块
var sum = require('./sum.js');
//3.加载第三方模块
const md5=require("md5");
登录后复制
(四)、模块作用域
- 和函数作用域类似,在自定义模块中定义的变量、方法等成员,只能在当前模块内被访问,这种模块级别的访问限制,叫做模块作用域。
- 模块作用域的好处:防止了全局变量污染的问题
二、npm与包
(一)、包的介绍
- Node.js 中的第三方模块又叫做包。包是由第三方个人或团队开发出来的,免费供所有人使用。
- Node.js 的内置模块仅提供了一些底层的 API,导致在基于内置模块进行项目开发的时,效率很低。
包是基于内置模块封装出来的,提供了更高级、更方便的 API,极大的提高了开发效率。 - 国外有一家 IT 公司,叫做 npm, Inc. 这家公司旗下有一个非常著名的网站: https://www.npmjs.com/ ,它是全球最大的包共享平台。
- 我们可以使用这个包管理工具, npm ,来对包进行管理,这个包管理工具随着 Node.js 的安装包一起被安装到了用户的电脑上。检测其版本。
npm -v
(二)、npm的使用
npm init
进行初始化,生成package.json
文件,记录项目的信息,记录包的信息npm install 包名
npm i 包名
下载包,放到node_modules
文件夹里npm i 包名 --save
npm i 包名 -S
(开发环境中)npm i 包名 --save-dev
npm i 包名 -D
(生产环境中)npm list
列举当前目录下安装的包npm i 包名@1
安装指定的版本npm i 包名 -g
安装全局包npm uninstall 包名
卸载包
(三)、全局安装nrm nodemon
手动切换方法:
npm config set registry=https://registry.npm.taobao.org
登录后复制
安装 nrm:
$ npm i nrm -g
登录后复制
查看nrm 内置的几个 npm 源的地址:
$ nrm ls
登录后复制
结果如下:
npm ---- https://registry.npmjs.org/
cnpm --- http://r.cnpmjs.org/
* taobao - https://registry.npm.taobao.org/
nj ----- https://registry.nodejitsu.com/
rednpm - http://registry.mirror.cqupt.edu.cn/
npmMirror https://skimdb.npmjs.com/registry/
edunpm - http://registry.enpmjs.org/
登录后复制
切换nrm:
$ nrm use npm
登录后复制
查看当前的镜像源:
npm config get register
登录后复制
(四)、淘宝cnpm工具
淘宝 NPM 镜像是一个完整 npmjs.org 镜像,你可以用此代替官方版本(只读),同步频率目前为 10分钟 一次以保证尽量与官方服务同步。
你可以使用淘宝定制的 cnpm (gzip 压缩支持) 命令行工具代替默认的 npm:
npm install -g cnpm -registry=https://registry.npm.taobao.org
登录后复制
安装包
cnpm install [模块名]
登录后复制
三、路由
express
一、下载与安装
$ npm install express --save
登录后复制
二、路由
路由的定义由如下结构组成:
app.METHOD(PATH, HANDLER)
登录后复制
名称 | 描述 |
---|---|
app | app 是一个 express 实例 |
METHOD | METHOD用于指定要匹配的HTTP请求方式 |
PATH | PATH是服务器端的路径 |
HANDLER | 是当路由匹配时需要执行的处理程序(回调函数) |
路由路径和请求方法一起定义了请求的端点,它可以是字符串,字符串模式以及正则表达式。
app.get('/', function (req, res) {
res.send('root')})app.get('/about', function (req, res) {
res.send('about')})app.get('/random.text', function (req, res) {
res.send('random.text')})
登录后复制
使用字符串模式的路由路径示例:
app.get('/ab?cd', function (req, res) {
res.send('ab?cd') //abcd ,acd})app.get('/ab/:id', function (req, res) {
res.send('ab/:id') })app.get('/ab+cd', function (req, res) {
res.send('ab+cd') //b可以一次或者多次的重复})app.get('/ab*cd', function (req, res) {
res.send('ab*cd') //在ab,cd之间随意写入任意字符})app.get('/ab(cd)?e', function (req, res) {
res.send('ab(cd)?e')})
登录后复制
可以为请求处理提供多个回调函数,其行为类似中间件。
app.get('/example/b', function (req, res, next) {
console.log('the response will be sent by the next function ...')
next()}, function (req, res) {
res.send('Hello from B!')})
登录后复制
var cb0 = function (req, res, next) {
console.log('CB0')
next()}var cb1 = function (req, res, next) {
console.log('CB1')
next()}var cb2 = function (req, res) {
res.send('Hello from C!')}app.get('/example/c', [cb0, cb1, cb2])
登录后复制
var cb0 = function (req, res, next) {
console.log('CB0')
next()}var cb1 = function (req, res, next) {
console.log('CB1')
next()}app.get('/example/d', [cb0, cb1], function (req, res, next) {
console.log('the response will be sent by the next function ...')
next()}, function (req, res) {
res.send('Hello from D!')})
登录后复制
三、中间件
1.应用级中间件
//万能中间件var express = require('express')var app = express()app.use(function (req, res, next) {
console.log('Time:', Date.now())
next()})
登录后复制
//特定路由的应用中间件app.use("/login",function (req, res, next) {
console.log('Time:', Date.now())})
登录后复制
2.路由级中间件
路由器级中间件的工作方式与应用级中间件相同,只是它绑定到express.Router()
.
var router = express.Router()
登录后复制
var express = require('express')var app = express()var router = express.Router()router.use(function (req, res, next) {
console.log('Time:', Date.now())
next()})router.get('/user/:id', function (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()}, function (req, res, next) {
console.log('Request Type:', req.method)
next()})
登录后复制
3.错误处理中间件
app.use(function (err, req, res, next) {
console.error(err.stack)
res.status(404).send('Something broke!')})
登录后复制
4.内置中间件
express.static提供静态资源,例如 HTML 文件、图像等。
express.json使用 JSON 有效负载解析传入请求。注意:可用于 Express 4.16.0+
// 应用级别中间件,获取post--json参数app.use(express.json());
登录后复制express.urlencoded解析带有 URL 编码负载的传入请求。 注意:可用于 Express 4.16.0+
// 应用级别中间件,获取post--form参数app.use(express.urlencoded({extended:false}));
登录后复制
5.第三方中间件
四、获取请求参数
- req.query 是一个可获取客户端get请求 查询字符串 转成的对象,默认为{}。
- req.body 包含在请求体中提交的数据键值对。默认情况下undefined,当使用解析中间件
express.json()
、express.urlencoded()
五、静态资源托管
语法:
express.static
内置中间件函数语法:
express.static(root, [options])
登录后复制
- root参数指定提供静态资源的根目录。
静态资源示例:
例如,通过如下代码就可以将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了:
app.use(express.static('public'))
登录后复制
现在,你就可以访问 public 目录中的所有文件了:
http://localhost:3000/images/kitten.jpg
http://localhost:3000/css/style.css
http://localhost:3000/js/app.js
http://localhost:3000/images/bg.png
http://localhost:3000/hello.html
登录后复制
多个静态资源目录:
如果要使用多个静态资源目录,请多次调用 express.static
中间件函数:
app.use(express.static('public'))
app.use(express.static('uploads'))
登录后复制
访问静态资源文件时,express.static
中间件函数会根据目录的添加顺序查找所需的文件。
虚拟路径:(非得添加static,没有意义)
express.static
中间件函数可以为某些静态资源服务创建虚拟路径前缀(该路径实际上并不存在于文件系统中),请指定静态目录的挂载路径,如下所示:
app.use('/static', express.static('public'))
登录后复制
现在,你就可以通过带有 /static
前缀地址来访问 public
目录中的文件了。
http://localhost:3000/static/images/kitten.jpg
http://localhost:3000/static/css/style.css
http://localhost:3000/static/js/app.js
http://localhost:3000/static/images/bg.png
http://localhost:3000/static/hello.html
登录后复制
六、模板引擎
一、.服务端渲染 SSR
- 做好静态页面,动态效果
- 把前端代码提供给后端,后端要把静态html以及里面的假数据给删掉,通过模板进行动态生成html的内容
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jL70ca3p-1658387147221)(C:Users11933Desktop前端全栈课件前后台交互imgs服务器端渲染.png)]
二、前后端分离,BSR
- 做好静态页面,动态效果
- json模拟,ajax动态创建页面
- 真实接口数据,前后联调
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pXRCidw2-1658387147223)(C:Users11933Desktop前端全栈课件前后台交互imgs前后端分离.png)]
三、模板引擎
Express模板引擎
与 Express 一起使用的一些流行模板引擎是Pug、 Mustache和EJS。Express 应用程序生成器默认使用Pug,但它也支持其他几个。
需要在应用中进行如下设置才能让Express渲染模板引擎:
- views,放模板文件的目录。例如:
app.set('views', './views')
。 - view engine,要使用的模板引擎。例如,要使用 Pug 模板引擎:
app.set('view engine', 'pug')
.
在路由中渲染模板
在路由渲染模板并将渲染后的 HTML 字符串发送到客户端。
res.render(view [, locals] [, callback])
登录后复制
- view:一个字符串,view是要渲染的模板文件的文件路径。
- locals:一个对象,其属性定义视图的局部变量。
app.get('/', function (req, res) {
res.render('index', { title: 'Hey', message: 'Hello there!' })
})
登录后复制
四、ejs模板引擎的使用
安装ejs
npm install ejs
登录后复制
在express配置ejs模板引擎
使用ejs模板引擎
在app.js中添加如下代码,配置Express使用ejs模板引擎。
app.set('views',path.join(__dirname,'views')); //设置模板存储位置app.set('view engine','ejs');
登录后复制
设置模板后缀为html
在app.js中添加如下代码,配置Express使用ejs模板引擎。并指定模板后缀名为html。
app.set('views',path.join(__dirname,'views')); //设置模板存储位置app.set('view engine','html');app.engine('html',require('ejs').renderFile); //使用ejs模板引擎解析html
登录后复制
ejs模板语法
<%= %> 输出标签
<%- %> 输出html标签(html会被浏览器解析)
<%# %> 注释标签
<% %> 流程控制标签(写的是if,else,for)
<%- include("user/show",{user:user})%> 导入公共的模板内容
登录后复制
MVC框架:
JSON:
一、概念:
二、JSON的两种结构
对象结构:对象结构在 JSON 中表示为 { } 括起来的内容。数据结构为 { key: value, key: value, … } 的键值对结构。其中,key 必须是使用英文的双引号包裹的字符串,value 的数据类型可以是数字、字符串、布尔值、null、数组、对象6种类型。
{ "name": "zs", "age": 20, "gender": "男", "hobby": ["吃饭", "睡觉"]}
登录后复制数组结构:数组结构在 JSON 中表示为 [ ] 括起来的内容。数据结构为 [ “java”, “javascript”, 30, true … ] 。数组中数据的类型可以是数字、字符串、布尔值、null、数组、对象6种类型。
[ 100, 200, 300 ][ true, false, null ][ { "name": "zs", "age": 20}, { "name": "ls", "age": 30} ][ [ "aaa", "bbb", "ccc" ], [ 1, 2, 3 ] ]
登录后复制
三、JSON语法的注意事项
- 属性名必须使用双引号包裹
- 字符串类型的值必须使用双引号包裹
- JSON 中不允许使用单引号表示字符串
- JSON 中不能写注释
- JSON 的最外层必须是对象或数组格式
- 不能使用 undefined 或函数作为 JSON 的值
- JSON 的作用:在计算机与网络之间存储和传输数据
- JSON 的本质:用字符串来表示 Javascript 对象数据或数组数据
四、JSON和JS对象的关系
JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。
//这是一个对象var obj = {a: 'Hello', b: 'World'}//这是一个 JSON 字符串,本质是一个字符串var json = '{"a": "Hello", "b": "World"}'
登录后复制
五、JSON和JS对象的互转
- 要实现从 JSON 字符串转换为 JS 对象,使用 JSON.parse() 方法
- 要实现从 JS 对象转换为 JSON 字符串,使用 JSON.stringify() 方法
HTTP
一、概念
二、请求(请求报文)
请求消息的组成
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G502I2rT-1658387147224)(C:Users11933Desktop前端全栈课件前后台交互imgs请求消息组成部分.png)]
- 请求行:由请求方式(get,post)、URL (/login?)和 HTTP 协议版本 3 个部分组成,他们之间使用空格隔开。
- 请求头部:用来描述客户端的基本信息,从而把客户端相关的信息告知服务器。请求头部由多行 键/值对 组成,每行的键和值之间用英文的冒号分隔。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ImfA8U4y-1658387147225)(C:Users11933Desktop前端全栈课件前后台交互imgs请求头部字段.png)]
- 空行:最后一个请求头字段的后面是一个空行,通知服务器请求头部至此结束。请求消息中的空行,用来分隔请求头部与请求体。
- 请求体:请求体中存放的,是要通过 POST 方式提交到服务器的数据。只有 POST 请求才有请求体,GET 请求没有请求体!
三、响应(响应报文)
响应消息的组成:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N0rfsHa8-1658387147225)(C:Users11933Desktop前端全栈课件前后台交互imgs响应消息组成部分.png)]
- 状态行:由 HTTP 协议版本、状态码和状态码的描述文本 3 个部分组成,他们之间使用空格隔开;
- 响应头部:用来描述服务器的基本信息。响应头部由多行 键/值对 组成,每行的键和值之间用英文的冒号分隔。
- 空行:在最后一个响应头部字段结束之后,会紧跟一个空行,用来通知客户端响应头部至此结束。响应消息中的空行,用来分隔响应头部与响应体。
- 响应体:中存放的,是服务器响应给客户端的资源内容。
四、HTTP请求方法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vwQMQrAp-1658387147226)(C:Users11933Desktop前端全栈课件前后台交互imgshttp请求的方法.png)]
五、响应的状态码
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-28YRkP8m-1658387147227)(C:Users11933Desktop前端全栈课件前后台交互imgshttp响应状态码.png)]
Ajax:
一、概念
二、XML
- XML 指可扩展标记语⾔,HTML 超文本标记语言
- XML被设计用来传输和存储数据
- XML和HTML类似,不同的是HTML都是预定义的标签,而XML没有预定义标签,全部都是自定义的标签,用来表示一些数据。
'{"title":"三体","author":"zs","price":30}'<book>
<title>三体</title>
<author>刘慈欣</author>
<price>30.00</price></book>
登录后复制
三、特点
优点:
- 可以无需刷新页面与服务器进行通信
- 允许你根据用户事件来更新部分页面内容
缺点:
- 没有浏览历史不能回退
- 存在跨越问题 同源策略:协议,域名,端口号
- SEO不友好
四、发送请求
- get方式,以及请求参数
// 1.创建对象var xhr=new XMLHttpRequest();// 2.初始化,设置请求方法和urlxhr.open("GET","http://127.0.0.1:3000/server?username=zs&password=1234");// 3.发送xhr.send();// 4.绑定事件,处理服务端返回得结果// readstate xhr得属性 状态 0,1,2,3,4xhr.onreadystatechange=function(){
// 服务器返回得结果
if(xhr.readyState==4){
// 判断响应得状态码
if(xhr.status==200){
// 行,头,体
console.log(xhr.status);
console.log(xhr.statusText);
console.log(xhr.response);
console.log(xhr.getAllResponseHeaders());
}
}}
登录后复制
项目:
一、对密码进行加密处理
使用步骤:
- 运行如下命令,安装
CryptoJS
:
npm i crypto-js
登录后复制
- 在
/login.js
中,导入crypto-js
:
const crypto = require('crypto-js')
登录后复制
- 以
ASE
进行纯文本加密:
//加密var a=crypto.AES.encrypt("abc","key").toString(); //SecrectKey 秘钥//解密var b=crypto.AES.decrypt(a,"key").toString(crypto.enc.Utf8); //按照UTF8编码解析出原始字符串
登录后复制
二、表单校验规则
步骤:
- 安装
joi
包,为表单中携带的每个数据项,定义验证规则:
npm install joi
登录后复制
- 安装
@escook/express-joi
中间件,来实现自动对表单数据进行验证的功能:
npm i @escook/express-joi
登录后复制
- 新建
/schema/login.js
用户信息验证规则模块:
const joi = require('joi')/**
* string() 值必须是字符串
* alphanum() 值只能是包含 a-zA-Z0-9 的字符串
* min(length) 最小长度
* max(length) 最大长度
* required() 值是必填项,不能为 undefined
* pattern(正则表达式) 值必须符合正则表达式的规则
*/// 用户名的验证规则const username = joi.string().required();// 密码的验证规则const password = joi.string().pattern(/^[S]{6,12}$/).required();// 登录表单的验证规则对象exports.login_schema = {
// 表示需要对 req.body 中的数据进行验证
body: {
username,
password,
},}
登录后复制
- 修改
/router/admin/login.js
中的代码:
// 1. 导入验证表单数据的中间件const expressJoi = require('@escook/express-joi')// 2. 导入需要的验证规则对象const { login_schema } = require('../../schema/login');// 3登录功能router.post("/",expressJoi(login_schema),(req,res)=>{}];
登录后复制
- 在
index.js
的全局错误级别中间件中,捕获验证失败的错误,并把验证失败的结果响应给客户端:
const joi = require('joi')// 错误中间件app.use(function (err, req, res, next) {
// 数据验证失败
if (err instanceof joi.ValidationError) return res.send(err);
// 未知错误
res.send(err)})
登录后复制
三、四种常见的POST提交数据方式
HTTP协议是以ASCII码传输,建立在TCP/IP协议之上的应用层规范。规范把 HTTP 请求分为三个部分:状态行、请求头、消息主体。协议规定 POST 提交的数据必须放在消息主体(entity-body)中,但协议并没有规定数据必须使用什么编码方式Content-Type。
服务端根据请求头(headers)中的Content-Type字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。所以说到POST提交数据方案,包含了Content-Type 和消息主体编码方式两部分。Content-Type的四种值分别代表四种方式,具体如下:
- 方式一:application/x-www-form-urlencoded
浏览器的原生form表单,如果不设置enctype属性,那么最终就会以 application/x-www-form-urlencoded方式提交数据。Content-Type被指定为application/x-www-form-urlencoded提交的数据按照key=val&key=val的方式进行编码,并且key和val都进行了URL转码。服务端例如 PHP 中,使用$_POST[′key′]可以获取到值。
- 方式二:multipart/form-data
常见的POST数据提交的方式。这种方式支持文件上传,不过必须要设置form的enctyped等于这个值。使用multipart/form-data方式会生成了一个boundary 来分割不同的字段,为了避免与正文重复,boundary是一段很长的随机拼接的字符串。然后Content-Type指明数据是以mutipart/form-data来编码并包括进本次请求的boundary 值。消息主体最后以 --boundary–标示结束。
- 方式三:application/json
由于JSON规范的流行,现在越来越多的开发者将application/json这个Content-Type作为响应头。用来告诉服务端消息主体是序列化后的JSON字符串。除了低版本IE之外各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理JSON的函数,JSON能格式支持比键值对复杂得多的结构化数据,普通键值对中的值只能是字符串,而使用json,键值对可以重复嵌套。
- 方式四:text/xml
它是一种使用HTTP作为传输协议,XML作为编码方式的远程调用规范。不过后来使用很少。也许在十多年前,在json还未出来之前数据交互对接。
总之application/x-www-form-urlencoded和multipart/form-data两种POST方式都是浏览器原生支持的,是普遍使用的两种方式,application/json是现在比较流行的新趋势。
四、multer
- 安装multer
npm i multer
登录后复制
- 导入multer
const multer = require('multer')
登录后复制
- 配置multer接收到的文件存储的文件夹和,存放的图片的名字
//上传文件存放路径、及文件命名const storage = multer.diskStorage({
destination: path.join(__dirname ,'../static/uploads'), //确定上传文件的物理位置
filename: function (req, file, cb) { //自定义设置文件的名字,根据上传时间的时间戳来命名
let type = file.originalname.split('.')[1]
cb(null, `${file.fieldname}-${Date.now().toString(16)}.${type}`)
}})
登录后复制
- 应用这个配置到multer实例里面
const upload = multer({storage});
登录后复制
- 在需要接收文件的路由里面应用upload.single(‘file’)中间件
(1).这个file是前端提交表单过来的时候表单的字段名称。(2).upload是用multer这个库里的顶级构造函数生成的实例。
登录后复制
- 总体思路梳理:
multer是啥? Multer是Express官方推出的,用于node.js 处理前端以multipart/form-data请求数据处理的一个中间件。注意: Multer 不会处理任何非 multipart/form-data 类型的表单数据
原理: Multer实例的single(‘###’) 是一个方法,这个方法被当作中间件放在某一个路由上时。就会给express 的 request 对象中添加一个 body 对象 以及 file 或 files 对象 。 body 对象包含表单的文本域信息,file 或 files 对象包含对象表单上传的文件信息。下图就是req.file的模样。当前端请求后台接口。匹配当前路由的时候,先经过这个multer中间件,这个中间件就会解析前端传过来的文件,会把文件保存在上面第三步配置文件解析完成后的文件夹内,名字也会重命名成上面第三步配置文件解析完成的文件名。同时,会在req的身上挂载一个file对象。这个file对象就是当前上传文件的信息。我们可以通过req.file.filename拿到这个重命名后的文件名,然后把这个文件名保存到数据库里面。前端如果想访问之前上传的图片,后台只需要把数据库里的文件名取到,随后映射成我们请求的路径,去请求public静态资源下的存放这些文件的文件夹就可以了。
multer是一个中间件,我建议把这个中间件写成一个单独的文件,最后把配置好的multer实例暴露出去,在需要他的路由里面当作中间件去应用它。就可以很快捷的处理前端发送过来的文件。而无需每个文件都写一遍。也更加符合我们模块化编程的思想。下图是我multer文件的配置。
五、富文本编辑器
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9D1VzMYl-1658387147228)(C:Users11933Desktop前端全栈课件前后台交互imgs富文本编辑器.png)]
layui 富文本编辑器(layedit):
使用:
<textarea id="demo" style="display: none;"></textarea>layui.use(['layedit'],function(){ layedit.build("demo")})
登录后复制layedit基础的方法:
方法名 描述 var index = layedit.build(id, options) 用于建立编辑器的核心方法index:即该方法返回的索引参数 id: 实例元素(一般为textarea)的id值参数 options:编辑器的可配置项,下文会做进一步介绍 layedit.set(options) 设置编辑器的全局属性即上述build方法的options layedit.getContent(index) 获得编辑器的内容参数 index: 即执行layedit.build返回的值 layedit.getText(index) 获得编辑器的纯文本内容参数 index: 同上 layedit.sync(index) 用于同步编辑器内容到textarea(一般用于异步提交)参数 index: 同上 layedit.getSelection(index) 获取编辑器选中的文本参数 index: 同上 编辑器属性设置:
属性 类型 描述 tool Array 重新定制编辑器工具栏,如: tool: [‘link’, ‘unlink’, ‘face’] hideTool Array 不显示编辑器工具栏,一般用于隐藏默认配置的工具bar height Number 设定编辑器的初始高度 uploadImage Object 设定图片上传接口,如:uploadImage: {url: ‘/upload/’, type: ‘post’} 富文本编辑器工具栏:
let richtextInex = layedit.build('richtext', { tool: [ 'strong' //加粗 , 'italic' //斜体 , 'underline' //下划线 , 'del' //删除线 , '|' //分割线 , 'left' //左对齐 , 'center' //居中对齐 , 'right' //右对齐 , 'image' //插入图片 ], uploadImage:{url:'/uploadrichtext',type:'POST'} })
登录后复制
六、express-session
(一)、Session简单介绍
session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 session 保存在服务器上。Session的用途:
session运行在服务器端,当客户端第一次访问服务器时,可以将客户的登录信息保存。
当客户访问其他页面时,可以判断客户的登录状态,做出提示,相当于登录拦截。
session可以和Redis或者数据库等结合做持久化操作,当服务器挂掉时也不会导致某些客户信息(购物车)
丢失。
(二)、Session的工作流程
当浏览器访问服务器并发送第一次请求时,服务器端会创建一个session对象,生成一个类似于
key,value的键值对,然后将key(cookie)返回到浏览器(客户)端,浏览器下次再访问时,携带key(cookie),
找到对应的session(value)。 客户的信息都保存在session中。
(三)、Cookie和Session区别:
cookie 数据存放在客户的浏览器上,session 数据放在服务器上。
cookie 不是很安全,别人可以分析存放在本地的 COOKIE 并进行 COOKIE 欺骗 考虑到安全应当使用 session。
session 会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能 考虑到减轻服务器性能方面,应当使用 COOKIE。
单个 cookie 保存的数据不能超过 4K,很多浏览器都限制一个站点最多保存 20 个 cookie。
(四)、express-session的使用
安装 express-session:
npm install express-session
登录后复制引入express-session:
var session = require("express-session");
登录后复制设置官方文档提供的中间件:
app.use(session({ secret: 'keyboard cat', resave: true, saveUninitialized: true }))
登录后复制使用:
设置值 req.session.username = "张三"; 获取值 req.session.username
登录后复制express-session的常用参数:
1. name - cookie的名字(原属性名为 key)。(默认:’connect.sid’)2. store - session存储实例3. secret - 用它来对session cookie签名,防止篡改4. cookie - session cookie设置 (默认:{ path: ‘/‘, httpOnly: true,secure: false, maxAge: null })5. genid - 生成新session ID的函数 (默认使用uid2库)6. rolling - 在每次请求时强行设置cookie,这将重置cookie过期时间(默认:false)7. resave - 强制保存session即使它并没有变化 (默认: true)8. proxy - 当设置了secure cookies(通过”x-forwarded-proto” header )时信任反向代理。当设定为true时,
”x-forwarded-proto” header 将被使用。当设定为false时,所有headers将被忽略。当该属性没有被设定时,将使用Express的trust proxy。9. saveUninitialized - 强制将未初始化的session存储。当新建了一个session且未设定属性或值时,它就处于
未初始化状态。在设定一个cookie前,这对于登陆验证,减轻服务端存储压力,权限控制是有帮助的。(默认:true)10. unset - 控制req.session是否取消(例如通过 delete,或者将它的值设置为null)。这可以使session保持
登录后复制
- express-session的常用方法:
1. Session.destroy():删除session,当检测到客户端关闭时调用。2. Session.reload():当session有修改时,刷新session。3. Session.regenerate():将已有session初始化。4. Session.save():保存session。
登录后复制
- 使用案例:
//配置中间件app.use(session({
secret: 'this is string key', // 可以随便写。一个 String 类型的字符串,作为服务器端生成 session 的签名
name:'session_id',/*保存在本地cookie的一个名字 默认connect.sid 可以不设置*/
resave: false, /*强制保存 session 即使它并没有变化,。默认为 true。建议设置成 false。*/
saveUninitialized: true, //强制将未初始化的 session 存储。 默认值是true 建议设置成true
cookie: {
maxAge:5000 /*过期时间*/
}, /*secure https这样的情况才可以访问cookie*/
//设置过期时间比如是30分钟,只要游览页面,30分钟没有操作的话在过期
rolling:true //在每次请求时强行设置 cookie,这将重置 cookie 过期时间(默认:false)}))
登录后复制
七、表单事件
- Form 对象属性:
属性 | 描述 |
---|---|
action | 接收请求的URL |
elements | 表单中的所有控件元素集合 |
length | 表单控件的个数 |
enctype | 编码类型 例:enctype=“multipart/form-data” |
name | 表单元素名称 |
- Form 对象方法:
方法 | 描述 |
---|---|
reset() | 把表单的所有输入元素重置为它们的默认值。 |
submit() | 提交表单。 |
- Form 对象事件:
事件 | 描述 |
---|---|
onreset | 在重置表单元素之前调用。 |
onsubmit | 在提交表单之前调用。 |
- 表单控件的属性:
属性 | 描述 |
---|---|
value | 获取和设置值 |
disabled | 获取或设置表单控件是否禁用值为true或 false |
type | 读取表单控件的类型 |
form | 所在表单元素对象 |
readOnly | 控件只读属性 Boolean 不能更改只能复制和读取 |
name | 获取与设置name字段名 |
- 表单控件的事件:
事件 | 描述 |
---|---|
onblur | 当失去焦点的时候 |
onfocus | 当获取焦点的时候 |
onchange | 当内容改变并失去焦点的时候 |
oninput | 在用户输入时触发 |
- 表单控件的方法:
方法 | 描述 |
---|---|
focus() | 获得焦点 |
blur() | 失去焦点 |
select() | 选择文本控件中的所有文本内容 |
以上就是总结Node.js模块开发及常用技巧分享的详细内容,更多请关注靠谱客其它相关文章!
最后
以上就是忧郁奇迹为你收集整理的总结Node.js模块开发及常用技巧分享的全部内容,希望文章能够帮你解决总结Node.js模块开发及常用技巧分享所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复