搜尋
首頁web前端js教程總結Node.js模組開發及常用技巧分享

一、模組化

模組化做為現代化的設計方法,這個概念最早起源於生產製造業。如今這個概念已經被各行各業來衍生應用,在軟體開發中也大量的採用了模組化想法。

所謂的模組化想法,將一個大程式依照功能劃分為若干個小的模組,每個小程式模組完成一個特定的功能,所有的模組按某種方法組裝起來,成為一個整體,完成整個系統所要求功能的程式設計方法。 【推薦:node.js影片教學

(一)、為什麼需要模組化

模組化可以讓你的程式碼低耦合,功能模組直接不相互影響。

為什麼需要模組化:

  • 程式複雜度上升程式碼越寫越多,在一個檔案裡程式碼就會越來越長,不易維護。 (把完成特定功能的程式碼分組,分別放到不同的檔案裡,這樣,每個檔案包含的程式碼就相對較少)

  • JavaScript 有複雜的依賴關係的時候就很容易出現一些變數的屬性或方法被覆蓋或改寫,導致變數污染。這是因為js沒有命名空間,不像其他語言透過命名空間可以有效的避免重名問題。

  • 想要存在JavaScript 私有的變數

#模組化想法解決問題:

  • 可維護性:每個模組都是單獨定義的,之間相互獨立。模組盡可能的需要和外部撇清關係,方便我們獨立的對其進行維護與改造。維護一個模組比在全局修改邏輯判斷要好的多。

  • 命名衝突:為了避免在JavaScript中的全域污染,我們透過模組化的方式利用函數作用域來建構命名空間,避免命名衝突。

  • 文件依賴:一個功能可能依賴一個或多個其他文件,使用是除了引入它本身還需要考慮依賴文件,透過模組化我們只需要引入文件,無需考慮文件依賴(模組化可以幫助我們解決文件依賴問題)。

  • 可重複使用性:雖然貼上複製很簡單,但是要考慮到我們之後的維護以及迭代。

(二)、什麼是Nodejs模組

為了讓Nodejs的檔案可以互相調用,Nodejs基於CommonJS規格提供了一個簡單的模組系統。 (nodejs實作並遵守CommonJS規範的)。

把具有公共功能的,抽離成一個單獨的js檔案作位一個模組。預設情況下,模組裡的方法或屬性,外面是無法存取的。如果想要在外面存取這些屬性,方法,就必須在模組裡透過exportsmodule.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

nrm 是一个管理 npm 源的工具。有时候国外资源太慢,使用这个就可以快速的在npm源间切换。

手动切换方法:

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 [模块名]

三、路由

路由:根据不同的路径返回不同的页面。

案例:server.js;static;route.js;route对象;render();api.js;封装server.js到index.js;合并对象

获取请求参数:login页面发get,post请求,到/api/login

静态资源托管:

express

Express是一个基于 Node.js 平台,快速、开放、极简的 Web 开发框架。

一、下载与安装

$ npm install express --save

案例:第一个express案例。

二、路由

所谓的路由就是客户端用来与后端服务器进行交互的一种方式,客户端采用特定的URL与请求方法来访问服务器端,服务器端通过响应返回特定资源。

路由的定义由如下结构组成:

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')})

可以为请求处理提供多个回调函数,其行为类似中间件。

案例:中间件f1,f2

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.应用级中间件

在Express程序中,使用 app.use()app.METHOD() 方法将中间件绑定到应用程序对象(app)。

凡是挂载在app身上的都是应用级中间件。

app.use() : 应用中的每个请求都可以执行其代码

//万能中间件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()})

案例: / ; /home , /list

3.错误处理中间件

与其他中间件函数相同的方式定义错误处理中间件函数,但是使用四个参数(err, req, res, next),放到最后。

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+

    application/json

    由于JSON规范的流行,现在越来越多的开发者将application/json这个Content-Type作为响应头。用来告诉服务端消息主体是序列化后的JSON字符串。除了低版本IE之外各大浏览器都原生支持 JSON.stringify,服务端语言也都有处理JSON的函数,JSON能格式支持比键值对复杂得多的结构化数据,普通键值对中的值只能是字符串,而使用json,键值对可以重复嵌套。

    // 应用级别中间件,获取post--json参数app.use(express.json());
  • express.urlencoded解析带有 URL 编码负载的传入请求。 注意:可用于 Express 4.16.0+

    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转码。

    // 应用级别中间件,获取post--form参数app.use(express.urlencoded({extended:false}));

5.第三方中间件

四、获取请求参数

  • req.query 是一个可获取客户端get请求 查询字符串 转成的对象,默认为{}。
  • req.body 包含在请求体中提交的数据键值对。默认情况下undefined,当使用解析中间件express.json()express.urlencoded()

五、静态资源托管

为了提供诸如图像、CSS 文件和 JavaScript 文件之类的静态文件,请使用 Express 中的 express.static 内置中间件函数。

语法:

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 在静态目录查找文件,因此,存放静态文件的目录名不会出现在 URL 中。

多个静态资源目录:

如果要使用多个静态资源目录,请多次调用 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

后端嵌套模板,后端渲染模板 (后端把页面组装起来)

  1. 做好静态页面,动态效果
  2. 把前端代码提供给后端,后端要把静态html以及里面的假数据给删掉,通过模板进行动态生成html的内容

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-jL70ca3p-1658387147221)(C:\Users\11933\Desktop\前端全栈\课件\前后台交互\imgs\服务器端渲染.png)]

二、前后端分离,BSR

(前后端分离,通过通用的json数据形式,不挑后端的语言)

  1. 做好静态页面,动态效果
  2. json模拟,ajax动态创建页面
  3. 真实接口数据,前后联调

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pXRCidw2-1658387147223)(C:\Users\11933\Desktop\前端全栈\课件\前后台交互\imgs\前后端分离.png)]

三、模板引擎

模板引擎能够在应用程序中使用静态模板文件。在运行时,模板引擎将模板文件中的变量替换为实际值,并将模板转换为发送给客户端的 HTML 文件。这种方法使设计 HTML 页面变得更加容易。

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');

注意:此时指定的模板目录为views,且模板文件的后缀名为.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

注意:此时指定的模板目录为views,且模板文件的后缀名为.html

ejs模板语法
   输出标签
   输出html标签(html会被浏览器解析)
   注释标签
    流程控制标签(写的是if,else,for)
  导入公共的模板内容

MVC框架:

是一种设计模式,是软件架构得模式,是在web开发过程中总结的一些套路或者是模块化的内容。M是指业务模型(module),V是指用户界面(view),C则是控制器(controller)。使用mvc最大的优势就是分层,目的是将M和V的实现代码分离,存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新。MVC是相互独立的,M,C(后端); V(前端)。路由规划为Controller。

JSON:

一、概念:

JSON(JavaScript Object Notation, JS对象表示法)简单来讲,JSON 就是 Javascript 对象和数组的字符串表示法,因此,JSON 的本质是字符串。

作用:JSON 是一种轻量级的文本数据交换格式,在作用上类似于 XML,专门用于存储和传输数据,但是 JSON 比 XML 更小、更快、更易解析。

现状:JSON 是在 2001 年开始被推广和使用的数据格式,到现今为止,JSON 已经成为了主流的数据交换格式。

二、JSON的两种结构

JSON 就是用字符串来表示 Javascript 的对象和数组。所以,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

一、概念

HTTP 协议即超文本传送协议 (HyperText Transfer Protocol) ,它规定了客户端与服务器之间进行网页内容传输时,所必须遵守的传输格式。(是一种约定与规则)

二、请求(请求报文)

客户端发起的请求叫做 HTTP 请求,客户端发送到服务器的消息,叫做 HTTP 请求消息,又叫做 HTTP 请求报文。

请求消息的组成

HTTP 请求消息由请求行(request line)、请求头部( header ) 、空行 和 请求体 4 个部分组成。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G502I2rT-1658387147224)(C:\Users\11933\Desktop\前端全栈\课件\前后台交互\imgs\请求消息组成部分.png)]

  • 请求行:由请求方式(get,post)、URL (/login?)和 HTTP 协议版本 3 个部分组成,他们之间使用空格隔开。
  • 请求头部:用来描述客户端的基本信息,从而把客户端相关的信息告知服务器。请求头部由多行 键/值对 组成,每行的键和值之间用英文的冒号分隔。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ImfA8U4y-1658387147225)(C:\Users\11933\Desktop\前端全栈\课件\前后台交互\imgs\请求头部字段.png)]

  • 空行:最后一个请求头字段的后面是一个空行,通知服务器请求头部至此结束。请求消息中的空行,用来分隔请求头部与请求体。
  • 请求体:请求体中存放的,是要通过 POST 方式提交到服务器的数据。只有 POST 请求才有请求体,GET 请求没有请求体!

三、响应(响应报文)

响应消息就是服务器响应给客户端的消息内容,也叫作响应报文。

响应消息的组成:

HTTP响应消息由状态行、响应头部、空行 和 响应体 4 个部分组成。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N0rfsHa8-1658387147225)(C:\Users\11933\Desktop\前端全栈\课件\前后台交互\imgs\响应消息组成部分.png)]

  • 状态行:由 HTTP 协议版本、状态码和状态码的描述文本 3 个部分组成,他们之间使用空格隔开;
  • 响应头部:用来描述服务器的基本信息。响应头部由多行 键/值对 组成,每行的键和值之间用英文的冒号分隔。
  • 空行:在最后一个响应头部字段结束之后,会紧跟一个空行,用来通知客户端响应头部至此结束。响应消息中的空行,用来分隔响应头部与响应体。
  • 响应体:中存放的,是服务器响应给客户端的资源内容。

四、HTTP请求方法

HTTP 请求方法,属于 HTTP 协议中的一部分,请求方法的作用是:用来表明要对服务器上的资源执行的操作。最常用的请求方法是 GET 和 POST。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vwQMQrAp-1658387147226)(C:\Users\11933\Desktop\前端全栈\课件\前后台交互\imgs\http请求的方法.png)]

五、响应的状态码

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-28YRkP8m-1658387147227)(C:\Users\11933\Desktop\前端全栈\课件\前后台交互\imgs\http响应状态码.png)]

Ajax:

一、概念

AJAX 全称为(Asynchronous JavaScript And XML),是异步的JavaScript和XML。通过 ajax可以在浏览器向服务器发送异步请求。最大的优势,无刷新获取数据 。也就是说AJAX可以在不重新加载整个页面的情况下,与服务器交换数据。这种异步交互的方式,使用户单击后,不必刷新页面也能获取新数据。使用Ajax,用户可以创建接近本地桌面应用的直接、高可用、更丰富、更动态的Web用户界面。

二、XML

  • XML 指可扩展标记语⾔,HTML 超文本标记语言
  • XML被设计用来传输和存储数据
  • XML和HTML类似,不同的是HTML都是预定义的标签,而XML没有预定义标签,全部都是自定义的标签,用来表示一些数据。

最开始是前后台进行数据交互的语言,现在是JSON。

'{"title":"三体","author":"zs","price":30}'<book>
    <title>三体</title>
    <author>刘慈欣</author>
    <price>30.00</price></book>

三、特点

优点:

  1. 可以无需刷新页面与服务器进行通信
  2. 允许你根据用户事件来更新部分页面内容

缺点:

  1. 没有浏览历史不能回退
  2. 存在跨越问题 同源策略:协议,域名,端口号
  3. 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());
        }
    }}

项目:

一、对密码进行加密处理

JavaScript使用CryptoJS加解密。CryptoJS时一个JavaScript的加解密的工具包。它支持多种的算法:MD5、SHA1、SHA2、SHA3、RIPEMD-160 哈希散列,进行 AES、DES、Rabbit、RC4、Triple DES 加解密。在项目中如果要对前后端传输的数据双向加密, 比如避免使用明文传输用户名,密码等数据。 就需要对前后端数据用同种方法进行加密,方便解密。

使用步骤:

  • 运行如下命令,安装 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}`)
    }})

1.sotrage是一个配置对象。他是通过multer.diskstorage存储引擎生成的。multer.diskstorage需要传递一个配置对象,这里的配置对象里面接收两个参数。第一个参数为destination,它的值为一个路径字符串,代表的含义是当multer处理完成前端传递过来的文件之后要把这个文件存储在哪里。这个文件夹无需手动创建,在接受文件的时候会自动创建。这里建议使用path模块进行拼接,不容易出错。第二个参数为一个回调函数,这里形参要用三个进行占位。multer中间件在解析前端提交的文件的时候会调用这个方法,调用的时候会给这个filename指向的函数传递三个参数,第二个值为前端传递过来文件信息,第三个参数cb为一个函数,cb函数调用的第二个参数指定的就是当前解析完成后的保存到destination指向的目录的文件名。

  • 应用这个配置到multer实例里面
const upload = multer({storage});
  • 在需要接收文件的路由里面应用upload.single(‘file’)中间件
(1).这个file是前端提交表单过来的时候表单的字段名称。(2).upload是用multer这个库里的顶级构造函数生成的实例。
  • 总体思路梳理:

实际网页开发当中,我们前端需要向后端提交一些像mp4,mp3,图片系列的东西,需要在后端进行接收。那么这里就可以使用Multer中间件来接收文件,对前端传递过来的文件做一些处理。

  1. multer是啥? Multer是Express官方推出的,用于node.js 处理前端以multipart/form-data请求数据处理的一个中间件。注意: Multer 不会处理任何非 multipart/form-data 类型的表单数据

  2. 原理: Multer实例的single(‘###’) 是一个方法,这个方法被当作中间件放在某一个路由上时。就会给express 的 request 对象中添加一个 body 对象 以及 file 或 files 对象 。 body 对象包含表单的文本域信息,file 或 files 对象包含对象表单上传的文件信息。下图就是req.file的模样。当前端请求后台接口。匹配当前路由的时候,先经过这个multer中间件,这个中间件就会解析前端传过来的文件,会把文件保存在上面第三步配置文件解析完成后的文件夹内,名字也会重命名成上面第三步配置文件解析完成的文件名。同时,会在req的身上挂载一个file对象。这个file对象就是当前上传文件的信息。我们可以通过req.file.filename拿到这个重命名后的文件名,然后把这个文件名保存到数据库里面。前端如果想访问之前上传的图片,后台只需要把数据库里的文件名取到,随后映射成我们请求的路径,去请求public静态资源下的存放这些文件的文件夹就可以了。

  3. multer是一个中间件,我建议把这个中间件写成一个单独的文件,最后把配置好的multer实例暴露出去,在需要他的路由里面当作中间件去应用它。就可以很快捷的处理前端发送过来的文件。而无需每个文件都写一遍。也更加符合我们模块化编程的思想。下图是我multer文件的配置。

五、富文本编辑器

富文本编辑器,Multi-function Text Editor, 简称 MTE, 是一种可内嵌于浏览器,所见即所得的文本编辑器。它提供类似于 Microsoft Word 的编辑功能,容易被不会编写 HTML 的用户并需要设置各种文本格式的用户所喜爱。

富文本编辑器不同于文本编辑器,程序员可到网上下载免费的富文本编辑器内嵌于自己的网站或程序里(当然付费的功能会更强大些),方便用户编辑文章或信息。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9D1VzMYl-1658387147228)(C:\Users\11933\Desktop\前端全栈\课件\前后台交互\imgs\富文本编辑器.png)]

layui 富文本编辑器(layedit):

  • 使用:

    <textarea></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模組開發及常用技巧分享的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:csdn。如有侵權,請聯絡admin@php.cn刪除
JavaScript在行動中:現實世界中的示例和項目JavaScript在行動中:現實世界中的示例和項目Apr 19, 2025 am 12:13 AM

JavaScript在現實世界中的應用包括前端和後端開發。 1)通過構建TODO列表應用展示前端應用,涉及DOM操作和事件處理。 2)通過Node.js和Express構建RESTfulAPI展示後端應用。

JavaScript和Web:核心功能和用例JavaScript和Web:核心功能和用例Apr 18, 2025 am 12:19 AM

JavaScript在Web開發中的主要用途包括客戶端交互、表單驗證和異步通信。 1)通過DOM操作實現動態內容更新和用戶交互;2)在用戶提交數據前進行客戶端驗證,提高用戶體驗;3)通過AJAX技術實現與服務器的無刷新通信。

了解JavaScript引擎:實施詳細信息了解JavaScript引擎:實施詳細信息Apr 17, 2025 am 12:05 AM

理解JavaScript引擎內部工作原理對開發者重要,因為它能幫助編寫更高效的代碼並理解性能瓶頸和優化策略。 1)引擎的工作流程包括解析、編譯和執行三個階段;2)執行過程中,引擎會進行動態優化,如內聯緩存和隱藏類;3)最佳實踐包括避免全局變量、優化循環、使用const和let,以及避免過度使用閉包。

Python vs. JavaScript:學習曲線和易用性Python vs. JavaScript:學習曲線和易用性Apr 16, 2025 am 12:12 AM

Python更適合初學者,學習曲線平緩,語法簡潔;JavaScript適合前端開發,學習曲線較陡,語法靈活。 1.Python語法直觀,適用於數據科學和後端開發。 2.JavaScript靈活,廣泛用於前端和服務器端編程。

Python vs. JavaScript:社區,圖書館和資源Python vs. JavaScript:社區,圖書館和資源Apr 15, 2025 am 12:16 AM

Python和JavaScript在社區、庫和資源方面的對比各有優劣。 1)Python社區友好,適合初學者,但前端開發資源不如JavaScript豐富。 2)Python在數據科學和機器學習庫方面強大,JavaScript則在前端開發庫和框架上更勝一籌。 3)兩者的學習資源都豐富,但Python適合從官方文檔開始,JavaScript則以MDNWebDocs為佳。選擇應基於項目需求和個人興趣。

從C/C到JavaScript:所有工作方式從C/C到JavaScript:所有工作方式Apr 14, 2025 am 12:05 AM

從C/C 轉向JavaScript需要適應動態類型、垃圾回收和異步編程等特點。 1)C/C 是靜態類型語言,需手動管理內存,而JavaScript是動態類型,垃圾回收自動處理。 2)C/C 需編譯成機器碼,JavaScript則為解釋型語言。 3)JavaScript引入閉包、原型鍊和Promise等概念,增強了靈活性和異步編程能力。

JavaScript引擎:比較實施JavaScript引擎:比較實施Apr 13, 2025 am 12:05 AM

不同JavaScript引擎在解析和執行JavaScript代碼時,效果會有所不同,因為每個引擎的實現原理和優化策略各有差異。 1.詞法分析:將源碼轉換為詞法單元。 2.語法分析:生成抽象語法樹。 3.優化和編譯:通過JIT編譯器生成機器碼。 4.執行:運行機器碼。 V8引擎通過即時編譯和隱藏類優化,SpiderMonkey使用類型推斷系統,導致在相同代碼上的性能表現不同。

超越瀏覽器:現實世界中的JavaScript超越瀏覽器:現實世界中的JavaScriptApr 12, 2025 am 12:06 AM

JavaScript在現實世界中的應用包括服務器端編程、移動應用開發和物聯網控制:1.通過Node.js實現服務器端編程,適用於高並發請求處理。 2.通過ReactNative進行移動應用開發,支持跨平台部署。 3.通過Johnny-Five庫用於物聯網設備控制,適用於硬件交互。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

VSCode Windows 64位元 下載

VSCode Windows 64位元 下載

微軟推出的免費、功能強大的一款IDE編輯器