热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

express.js的介绍及使用

Node.js《Node.js官网(中文)》Node.js《Node.js官网(英文)》Node.js是什么Node.js®isaJavaScriptruntime
  • Node.js 《Node.js 官网(中文)》
  • Node.js 《Node.js 官网(英文)》



Node.js 是什么

Node.js® is a Javascript runtime built on Chrome’s V8 Javascript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. Node.js’ package ecosystem, npm, is the largest ecosystem of open source libraries in the world.

1. Javascript 运行时
2. 既不是语言,也不是框架,它是一个平台

Node.js 中的 Javascript

1. 没有 BOM、DOM
2. 在 Node 中为 Javascript 提供了一些服务器级别的 API
2.1 fs 文件操作模块
2.2 http 网络服务构建模块
2.3 os 操作系统信息模块
2.4 path 路径处理模块
2.5 .....

I. express简介

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

简单来说,封装了node中http核心模块,专注于业务逻辑的开发。

安装方法


npm install express --save

koa

Koa – next generation web framework for node.js

Koa 是一个新的 web 框架,由 Express 幕后的原班人马打造, 致力于成为 web 应用和 API 开发领域中的一个更小、更富有表现力、更健壮的基石。 通过利用 async 函数,Koa 帮你丢弃回调函数,并有力地增强错误处理。 Koa 并没有捆绑任何中间件, 而是提供了一套优雅的方法,帮助您快速而愉快地编写服务端应用程序。(project:koa-1.js)

const Koa = require('koa');
const app = new Koa();
app.use(async ctx => {
ctx.body = 'Hello World';
});
app.listen(3000);

Hello XXX (node)


var http = require('http')
http.createServer(function (req, res) {
// 主页
if (req.url == "/") {
res.end("Holle hemo!");
}
// About页
else if (req.url == "/about") {
res.end("Hello about!");
}
}).listen('3009', 'localhost', function () {
console.log('listen 3009 ....')
})

project:demo-1.js Hello XXX 测试结果:

var app = express()
app.get('/', function (req, res) {
res.send('hello home ...')
})
app.get('/about', function (req, res) {
res.send('hello about ...')
})
app.listen(3000, function () {
console.log('express app is runing .....')
})

project:demo-2.js Hello XXX 测试结果:

// 访问路径 http://127.0.0.1:3000/public/a.js
app.use('/public/',express.static('./public/'))

require 方法的加载规则

–深入浅出 node.js

node 中存在的模块主要有:

  1. 核心模块 path fs http …
  2. 自己定义的模块 (路径形式的模块)
  3. 第三方模块 art-template express(使用npm安装的模块)


// 加载核心模块
const path = require('path');
// 加载自定义模块
const foo = require('./fooo.js')
// 加载第三方模块 node_modules
const express = require('express')

node 中require加载规则:

  1. 优先缓存加载
  2. 判断模块标识

    2.1 是否是核心模块 http 、fs 加载 缓存 export

    2.2 是否是文件模块 ./foo.js 加载 缓存 export

    2.3 是否是第三方模块 (第三方模块需要 npm install 安装)

    - node_modules/art-template/
    - node_modules/art-template/package.json
    - node_modules/art-template/package.json 中找main 作为文件加载入口
    - index.js 备选项
    - 进入上一级目录找 node_modules
    - 按照此规则依次向上查找,直到磁盘根目录找不到 报错 Can not find moudle XXX

node 中require加载规则:

res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});

router.post('/students/new', function (req, res) {
console.log(req.body)
Student.save(req.body, function (err) {
if (err) {
return res.status(500).send('Server error.')
}
res.redirect('/students')
})
})

post 提交方式测试:

path.basename(path[, ext])

node 中的其他成员

在每个模块中,除了require、export 等模块相关的API之外,还有两个特殊的成员

  • __dirname 可以用来获取当前文件模块所属目录的绝对路径 动态获取
  • __filename 可以用来获取当前文件的绝对路径 动态获取

1. 在文件操作路径中,相对路径设计的是相对于执行node命令所在路径
2. 模块中的路径标识就是相对于当前文件模块,不受执行node命令所处路径影响

const fs = require('fs')
const path = require('path')
// 文件操作中的相对路径
fs.readFile('c:/a/b/a.txt', 'utf-8', function (err, data) {
if (err) throw err
console.log(data)
})
// 文件操作中的相对路径转化为动态获取的绝对路径
fs.readFile(path.join(__dirname,'./a.txt'), 'utf-8', function (err, data) {
})
// 模块中的路径标识
require('./b')

II. Express 中间件

中间件(middleware) 在 Node.js 中被广泛使用,它泛指一种特定的设计模式、一系列的处理单元、过滤器和处理程序,以函数的形式存在,连接在一起,形成一个异步队列,来完成对任何数据的预处理和后处理。

常规的中间件模式

express 中间件

express 中间件

Middleware functions are functions that have access to the request object (req), the response object (res), and the next function in the application’s request-response cycle.

中间件的本质就是请求处理方法,把用户从请求到响应的整个过程分发到多个中间件中去处理,提高代码灵活性,动态可扩展

中间件的使用

var express = require('express')
var app = express()
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
console.log('After LOGGED')
}
var myLogger2 = function (req, res, next) {
console.log('LOGGED2')
next();
console.log('After LOGGED2')
}
app.use(myLogger)
app.use(myLogger2)
app.listen(3000, function () {
console.log('express app is runing .....')
})

project:demo-3.js 运行结果如下:

实现中间件机制

function express() {
var taskArrray = []
var app = function (req, res) {
var i = 0
function next() {
var task = taskArrray[i++]
if (!task) {
return;
}
task(req, res, next);
}
next();
}
// 将中间件存入数组中
app.use = function (task) {
taskArrray.push(task)
}
return app;
}

project:demo-4.js

实现中间件机制测试结果

var http = require('http')
var app = express();
http.createServer(app).listen('3000', function () {
console.log('listening 3000....');
});
var myLogger = function (req, res, next) {
console.log('LOGGED')
next()
console.log('After LOGGED')
}
var myLogger2 = function (req, res, next) {
console.log('LOGGED2')
next();
console.log('After LOGGED2')
}
app.use(myLogger)
app.use(myLogger2)

express 中间件分类

应用层级别中间件

  • 不关心请求路径和请求方法的中间件,任何请求都会执行
  • 关心请求路径的中间件

路由级别中间件

  • 不关心请求路径和请求方法的中间件,任何请求都会执行
  • 严格匹配请求方法和请求路径的中间件

错误处理中间件

  • 404页面 全局错误页面

内置中间件

  • express.static

第三方中间件

  • body-parser
  • COOKIE-session

使用express 中间件

project:demo-5.js

// 不关心请求路径和请求方法的中间件
app.use(function (req, res, next) {
console.log('all request must execute!!')
next()
})
app.use(function (req, res, next) {
console.log('all request must execute 1 !!')
})
// 以/XXX 开头的路径的中间件
app.use('/user/:id', function (req, res, next) {
console.log('Request URL:', req.originalUrl)
next()
}, function (req, res, next) {
console.log('Request Type:', req.method)
next()
})
// 严格匹配请求方法和请求路径的中间件
app.get('/aa/bb', function (req, res, next) {
console.log('/aa/bb')
next()
})

使用express 中间件

// 内置中间件
app.use('/public/', express.static('./public/'))
// 所有都匹配不到时 404 (放在最后)
app.use('/', router)
app.use(function (req, res, next) {
res.send('This is 404 !!!!!')
})
// 配置全局错误统一处理中间件
app.get('/aa/bb', function (req, res, next) {
fs.readFile('c:/a/b/index.js', 'utf-8', function (err) {
if (err) return next(err)
})
})
app.use(function (err, req, res, next) {
res.status(500).json({
err_code: 500,
err_msg: err.message
})
})
// 第三方级别中间件
const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());

III. Express Generator

通过应用生成器工具 express-generator 可以快速创建一个应用的骨架。

npm install express-generator -g
express myapp --view=pug
cd myapp
npm install
npm run start

project:myapp 访问http://localhost:3000/

目录结构与代码

1.查看myapp目录结构

2.结合中间件分析代码

project: myapp

var html = fn(locals);
// render
var html = pug.render('string of pug', merge(options, locals));

IV. express 在vue项目中模拟接口

结合ccs-operation-web中 模拟接口 ./api/server.js

project:app.js


运行express服务器

"scripts": {
"server": "nodemon api/server.js",
"dev": "webpack-dev-server --inline --progress --open --config build/webpack.dev.conf.js",
// 影响ccs-operation-web/config/proxyConfig.js http://localhost:3002/api/listContracts?pin=X&all=X
"devlocal": "shell-exec --colored-output \"npm run dev --local\" \"npm run server\"",
}

shell-executor

A small nodejs module to execute shell commands in parallel

npm i -g shell-executor
// --colored-output Use colored output in logs
shell-exec --colored-output 'npm run lint' 'npm run test' 'npm run watch'

ccs-operation-web ./api/server.js

const express = require('express');
const bodyParser = require('body-parser');
const request = require('request');
const path = require('path');
const walk = require('klaw-sync');
const {
origin_proxy_url,
local_proxy_port,
local_proxy_url
} = require('../config/proxyConfig');
const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
let _existRoutes = [];


app.use( (req, res, next)=>{
const {url, body, method} = req;
if (!~_existRoutes.indexOf(req.path)) {
const rurl = origin_proxy_url.replace(/\/$/, '') + url;
let r = method === 'POST'
? request.post({url: rurl, form: body}, (err, httpRes, reqBody)=>{
console.log(err, reqBody, body)
})
: request(rurl);
console.log(`本地未定义的请求,跳转到 ${method} ${rurl}`);
req.pipe(r).pipe(res);
return;
}
next();
});
//遍历本目录下的 *.api.js
walk(path.resolve('./'))
.filter(p=>/\.api\.js$/.test(p.path))
.map(p=>p.path)
.forEach(part=>require(part)(app));
//记录注册过的路由
_existRoutes = app._router.stack.filter(s=>s.route).map(s=>s.route.path);
app.listen(local_proxy_port, ()=>{
console.log(`\n\n local server running at ${local_proxy_url} \n\n`);
});

klaw-sync

klaw-sync is a Node.js recursive and fast file system walker

// 用法
const klawSync = require('klaw-sync')
const paths = klawSync('/some/dir')
// paths = [{path: '/some/dir/dir1', stats: {}}, {path: '/some/dir/file1', stats: {}}]

request

Request – Simplified HTTP client

// 用法
npm install request
var request = require('request');
request('http://www.google.com', function (error, response, body) {
console.log('error:', error);
console.log('statusCode:', response && response.statusCode);
console.log('body:', body);
});
req.pipe(request('http://mysite.com/doodle.png')).pipe(resp)

VI. 总结

express 基于 Node.js 平台,快速、开放、极简的 Web 开发框架

简单来说,封装了node中http核心模块,专注于业务逻辑的开发。

express 核心内容 : 理解、使用中间件

express 源码学习 路由
express 中间件原理


推荐阅读
  • 掌握PHP编程必备知识与技巧——全面教程在当今的PHP开发中,了解并运用最新的技术和最佳实践至关重要。本教程将详细介绍PHP编程的核心知识与实用技巧。首先,确保你正在使用PHP 5.3或更高版本,最好是最新版本,以充分利用其性能优化和新特性。此外,我们还将探讨代码结构、安全性和性能优化等方面的内容,帮助你成为一名更高效的PHP开发者。 ... [详细]
  • TypeScript 实战分享:Google 工程师深度解析 TypeScript 开发经验与心得
    TypeScript 实战分享:Google 工程师深度解析 TypeScript 开发经验与心得 ... [详细]
  • 基于Node.js的高性能实时消息推送系统通过集成Socket.IO和Express框架,实现了高效的高并发消息转发功能。该系统能够支持大量用户同时在线,并确保消息的实时性和可靠性,适用于需要即时通信的应用场景。 ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • 本文探讨了如何通过检测浏览器类型来动态加载特定的npm包,从而优化前端性能。具体而言,仅在用户使用Edge浏览器时加载相关包,以提升页面加载速度和整体用户体验。此外,文章还介绍了实现这一目标的技术细节和最佳实践,包括使用User-Agent字符串进行浏览器识别、条件加载策略以及性能监控方法。 ... [详细]
  • 本文详细介绍了在 Vue.js 前端框架中集成 vue-i18n 插件以实现多语言支持的方法。通过具体的配置步骤和示例代码,帮助开发者快速掌握如何在项目中实现国际化功能,提升用户体验。同时,文章还探讨了常见的多语言切换问题及解决方案,为开发人员提供了实用的参考。 ... [详细]
  • 本文详细探讨了Zebra路由软件中的线程机制及其实际应用。通过对Zebra线程模型的深入分析,揭示了其在高效处理网络路由任务中的关键作用。文章还介绍了线程同步与通信机制,以及如何通过优化线程管理提升系统性能。此外,结合具体应用场景,展示了Zebra线程机制在复杂网络环境下的优势和灵活性。 ... [详细]
  • CentOS 7环境下Jenkins的安装与前后端应用部署详解
    CentOS 7环境下Jenkins的安装与前后端应用部署详解 ... [详细]
  • Node.js 教程第五讲:深入解析 EventEmitter(事件监听与发射机制)
    本文将深入探讨 Node.js 中的 EventEmitter 模块,详细介绍其在事件监听与发射机制中的应用。内容涵盖事件驱动的基本概念、如何在 Node.js 中注册和触发自定义事件,以及 EventEmitter 的核心 API 和使用方法。通过本教程,读者将能够全面理解并熟练运用 EventEmitter 进行高效的事件处理。 ... [详细]
  • 在CentOS上部署和配置FreeSWITCH
    在CentOS系统上部署和配置FreeSWITCH的过程涉及多个步骤。本文详细介绍了从源代码安装FreeSWITCH的方法,包括必要的依赖项安装、编译和配置过程。此外,还提供了常见的配置选项和故障排除技巧,帮助用户顺利完成部署并确保系统的稳定运行。 ... [详细]
  • 本文深入解析了 Apache 配置文件 `httpd.conf` 和 `.htaccess` 的优化方法,探讨了如何通过合理配置提升服务器性能和安全性。文章详细介绍了这两个文件的关键参数及其作用,并提供了实际应用中的最佳实践,帮助读者更好地理解和运用 Apache 配置。 ... [详细]
  • Spring Boot 实战(一):基础的CRUD操作详解
    在《Spring Boot 实战(一)》中,详细介绍了基础的CRUD操作,涵盖创建、读取、更新和删除等核心功能,适合初学者快速掌握Spring Boot框架的应用开发技巧。 ... [详细]
  • 本文作为“实现简易版Spring系列”的第五篇,继前文深入探讨了Spring框架的核心技术之一——控制反转(IoC)之后,将重点转向另一个关键技术——面向切面编程(AOP)。对于使用Spring框架进行开发的开发者来说,AOP是一个不可或缺的概念。了解AOP的背景及其基本原理,对于掌握这一技术至关重要。本文将通过具体示例,详细解析AOP的实现机制,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 在处理大图片时,PHP 常常会遇到内存溢出的问题。为了避免这种情况,建议避免使用 `setImageBitmap`、`setImageResource` 或 `BitmapFactory.decodeResource` 等方法直接加载大图。这些函数在处理大图片时会消耗大量内存,导致应用崩溃。推荐采用分块处理、图像压缩和缓存机制等策略,以优化内存使用并提高处理效率。此外,可以考虑使用第三方库如 ImageMagick 或 GD 库来处理大图片,这些库提供了更高效的内存管理和图像处理功能。 ... [详细]
author-avatar
萝莉吴文娟
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有