基础:

初步理解:Node.js Express 框架

参见:[Node.js] 08 - Web Server and REST API

进阶:

Ref: 如何系统地学习 Express?【该网页有一些不错的资源】

express是一个基于node的web框架(集成web服务器+mvc),当然其实不用框架,使用node自己弄一个web服务器和mvc框架也不是很麻烦(Node为网络而生,当然强大的不止这点),但是有优秀的express,封装了很多常用功能,推荐用。

express主要依赖connect(基于node的http服务器框架,提供大量的中间件帮助用户构建强大灵活的web server),所以深入connect也是有必要的。

视频课程:Node.js + Express + MongoDB中文版,有comment】from rails365编程学院

比较实用,简短,也是本篇的学习重点。


Several popular Node.js frameworks are built on Express:

  • Feathers: Build prototypes in minutes and production ready real-time apps in days.
  • ItemsAPI: Search backend for web and mobile applications built on Express and Elasticsearch.
  • KeystoneJS: Website and API Application Framework / CMS with an auto-generated React.js Admin UI.
  • Kraken: Secure and scalable layer that extends Express by providing structure and convention.
  • LEAN-STACK: The Pure JavaScript Stack.
  • LoopBack: Highly-extensible, open-source Node.js framework for quickly creating dynamic end-to-end REST APIs.
  • MEAN: Opinionated fullstack JavaScript framework that simplifies and accelerates web application development.
  • Sails: MVC framework for Node.js for building practical, production-ready apps.
  • Bottr: Framework that simplifies building chatbot applications.
  • Hydra-Express: Hydra-Express is a light-weight library which facilitates building Node.js Microservices using ExpressJS.
  • Blueprint: Highly-configurable MVC framework for composing production-ready services from reusable components
  • Locomotive: Powerful MVC web framework for Node.js from the maker of Passport.js
  • graphql-yoga: Fully-featured, yet simple and lightweight GraphQL server
  • Express Gateway: Fully-featured and extensible API Gateway using Express as foundation

磨刀不误砍柴工

第二次,则以轻松学 nodejs - 基础篇为底料,结合之前的学习,再屡一下思路:

[Node.js] 01 - How to learn node.js【1】

[Node.js] 02 - Read Eval Print Loop【2-】

* 命令行交互,子命令

* 新建进程 - child_process模块 ----> 详见 [Node.js] 06

* shell模式

[Node.js] 03 - Buffer, Stream and File IO【2-】

* Buffer类操作

* 文件操作 - 异步同步

* 文件流操作

* 管道操作

* os模块

[Node.js] 04 - Event and Callback【2+】

其实就是“监听器”:

* 回调函数,比如:异步读取文件的回调函数

* 观察者监视事件,

* 结合setTimeout构成“延时触发”,还有setInterval。

* 继承 EventEmitter

* Error 事件,遇到异常的时候通常会触发。

[Node.js] 05 - Modules and Function【2+】

* 常用模块

* 自定义模块

* 函数作为参数

* 全局对象:global 的属性,若干常用属性,console 方法。

* 常用工具 - util

[Node.js] 06 - Multi-thread and process module

  * (略,另附专题)

[Node.js] 07 - Html and Http

[Node.js] 08 - Web Server and REST API  

* Node.js RESTful API

* Node.js 路由,功能分离判断url

* GET / POST 请求上传表单

* 服务端如何response html? file? stream?

* Node.js Express 框架有什么不同和优势?这是本篇接下来打算详述的内容。

[Node.js] 09 - Connect with Database

  • 其他:NPM, package json and nodemon
npm install express

npm install -g webpack

global:全局性的安装,以后可以直接使用webpack命令。

yarn是另一个较新的包管理器。

安装了什么包?通过package json来记录。

node_modules的内容很大,不是源码的一部分。

npm install  // 安装dependencies中的包在node_modules中

npm install --save express

npm install --save-dev gulp

npm run start  // 安装好了start中的内容,并修改相应的信息 in package.json.

dodemon,修改后自动更新网页,方便开发调试。

npm install -g nodemon,然后执行,开始自动监控所有文件的变化。

Nodejs + Express + MongoDB 基础篇


通过分装,相对于纯nodejs更有效率,表达更加简洁。

var express = require('express');
var app = express(); app.get('/', function(req, res) {
res.send("this is the homepage");  // 分装了包的建立,所以便捷性
// 也可以发送其他类型:json,数组,对象等
}); app.listen(3000);
console.log('listening to port 3000');

Express的路由比较强大!

  • 路由支持正则表达式
var express = require('express');
var app = express(); app.get('/profile/:id/user/:name', function(req, res) {
console.dir(req.params);
res.send("You requested to see a profile with the name of " + req.params.name);
});

// 支持正则表达式
app.get('/ab?cd', function(req, res) {
res.send('/ab?cd');
}) app.listen(3000);
console.log('listening to port 3000');
  • 处理url中的参数
var express = require('express');
var app = express(); app.get('/', function(req, res) {
/* .dir 显示一个对象所有的属性和方法 */
console.dir(req.query);
res.send("home page: " + req.query.find);
});
app.get('/profile/:id/user/:name', function(req, res) {
console.dir(req.params);
res.send("You requested to see a profile with the name of " + req.params.name);
}); app.get('/ab?cd', function(req, res) {
res.send('/ab?cd');
}) app.listen(3000);
console.log('listening to port 3000');
  • Post请求 - 表单上传

npm install body-parser --save

结合postman发送伪数据包来进行测试。

var express = require('express');
var bodyParser = require('body-parser') var app = express();
// create application/json parser
var jsonParser = bodyParser.json() // create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false })  // app.get('/', function(req, res) {
console.dir(req.query);
res.send("home page: " + req.query.find);
}); app.post('/', urlencodedParser, function(req, res) {
console.dir(req.body);
res.send(req.body.name);
});

------------------------------------------------------------------
app.post('/upload', jsonParser, function(req, res) {
console.dir(req.body);
res.send(req.body.name);
}); app.get('/profile/:id/user/:name', function(req, res) {
console.dir(req.params);
res.send("You requested to see a profile with the name of " + req.params.name);
}); app.get('/ab?cd', function(req, res) {
res.send('/ab?cd');
}) app.listen(3000);
console.log('listening to port 3000');
  • Post请求 - 文件上传

参见:[Node.js] 08 - Web Server and REST API - Node.js Express 框架

* Switch请求各种资源

* 如果获得的是静态文件

* GET 方法

* POST 方法

* 文件上传

* Cookie 管理

推荐参考:Nodejs进阶:基于express+multer的文件上传

* 环境初始化

* 基础例子:单图上传

* 基础例子:多图上传

* 获取上传的图片的信息

* 自定义文件上传路径、名称

  • EJS,一个模板引擎

(1) 原始方法,看上去复杂,因为竟然有两行,而不是一行。

(2) 可以直接使用sendFile。

(3) 继续添加变量。

npm install ejs --save

需要达到的效果:

Ref: 将模板引擎用于 Express【使用了 pug 例子,本篇则使用 EJS

. / server.js

var express    = require('express');
var bodyParser = require('body-parser');
var fs = require('fs'); var app = express(); app.set('view engine', 'ejs'); var multer = require('multer'); var createFolder = function(folder) {
try {
fs.accessSync(folder);
} catch (e) {
fs.mkdirSync(folder);
}
}; var uploadFolder = './upload/'; createFolder(uploadFolder); var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, uploadFolder);
},
filename: function(req, file, cb) {
cb(null, file.originalname);
}
}); var upload = multer({ storage: storage }); // create application/json parser
var jsonParser = bodyParser.json() // create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false }) app.get('/', function(req, res) {
console.dir(req.query);
res.send("home page: " + req.query.find);
});

-----------------------------------------------------------------------------------
模板引擎,在HTML中动态的嵌入变量
-----------------------------------------------------------------------------------
app.get('/form/:name', function(req, res) {
var person = req.params.name;
res.render('form', { person: person });  // ---->
}); 可见,不用再写.html了,成了动态变量。 -----------------------------------------------------------------------------------
app.post('/', urlencodedParser, function(req, res) {
console.dir(req.body);
res.send(req.body.name);
}); app.post('/upload', upload.single('logo'), function(req, res) {
console.dir(req.file);
res.send({ 'ret_code': 0 });
}); app.get('/profile/:id/user/:name', function(req, res) {
console.dir(req.params);
res.send("You requested to see a profile with the name of " + req.params.name);
}); app.get('/ab?cd', function(req, res) {
res.send('/ab?cd');
}) app.listen(3000);
console.log('listening to port 3000');

. / views / form.ejs

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head> <body>
<h1>
<%= person %>
</h1>
<form action="/upload" method="post" enctype="multipart/form-data">
<h2>单图上传</h2>
<input type="file" name="logo">
<input type="submit" value="提交">
</form>
</body> </html>

Ref: Node.js + Express + MongoDB 基础篇 #8 使用模板引擎

server.js

var express = require('express');
var bodyParser = require('body-parser');
var fs = require('fs'); var app = express(); app.set('view engine', 'ejs'); var multer = require('multer'); var createFolder = function(folder) {
try {
fs.accessSync(folder);
} catch (e) {
fs.mkdirSync(folder);
}
}; var uploadFolder = './upload/'; createFolder(uploadFolder); var storage = multer.diskStorage({
destination: function(req, file, cb) {
cb(null, uploadFolder);
},
filename: function(req, file, cb) {
cb(null, file.originalname);
}
}); var upload = multer({ storage: storage }); // create application/json parser
var jsonParser = bodyParser.json() // create application/x-www-form-urlencoded parser
var urlencodedParser = bodyParser.urlencoded({ extended: false }) app.get('/', function(req, res) {
console.dir(req.query);
res.send("home page: " + req.query.find);
}); app.get('/form/:name', function(req, res) {
var data = { age: 29, job: "programmer", hobbie: ['eating', 'fighting', 'fishing'] };
res.render('form', { data: data });
}); app.get('/about', function(req, res) {
res.render('about');
}); app.post('/', urlencodedParser, function(req, res) {
console.dir(req.body);
res.send(req.body.name);
}); app.post('/upload', upload.single('logo'), function(req, res) {
console.dir(req.file);
res.send({ 'ret_code': 0 });
}); app.get('/profile/:id/user/:name', function(req, res) {
console.dir(req.params);
res.send("You requested to see a profile with the name of " + req.params.name);
}); app.get('/ab?cd', function(req, res) {
res.send('/ab?cd');
}) app.listen(3000);
console.log('listening to port 3000');

form.ejs

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head> <body>
<%- include('partials/header.ejs') -%>
<h1>
<%= data.age %>
<h2>hobbie</h2>
<ul>
<% data.hobbie.forEach(function(item) { %>
<li>
<%= item %>
</li>
<% }) %>
</ul>
</h1>
<form action="/upload" method="post" enctype="multipart/form-data">
<h2>单图上传</h2>
<input type="file" name="logo">
<input type="submit" value="提交">
</form>
</body> </html>

about.ejs

<!DOCTYPE html>
<html lang="en"> <head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head> <body>
<%- include('partials/header.ejs') -%>
<p>about page</p>
</body> </html>

header.ejs

<nav>
<ul>
<li><a href="">home</a></li>
<li><a href="">about</a></li>
</ul>
</nav>

Unfinished...

[React] 05 - Route: connect with ExpressJS的更多相关文章

  1. [React] React Router: Route Parameters

    A router library is no good if we have to hardcode every single route in our application. In this le ...

  2. [React] 06 - Route: koa makes your life easier

    听说koa比express更傻瓜化,真的? Koa 框架教程 本身代码只有1000多行,所有功能都通过插件实现,很符合 Unix 哲学. 搭建简单服务器 Koa, 架设一个简单的服务器 // demo ...

  3. react dva 的 connect 与 @connect

    https://dvajs.com/guide/introduce-class.html#connect-方法 connect的作用是将组件和models结合在一起.将models中的state绑定到 ...

  4. [Full-stack] 快速上手开发 - React

    故事背景 [1] 博客笔记结合<React快速上手开发>再次系统地.全面地走一遍. [2] React JS Tutorials:包含了JS --> React --> Red ...

  5. [React] 08 - Tutorial: evolution of code-behind

    有了七篇基础学习,了解相关的知识体系,之后便是系统地再来一次. [React] 01 - Intro: javaScript library for building user interfaces ...

  6. [React] 10 - Tutorial: router

    Ref: REACT JS TUTORIAL #6 - React Router & Intro to Single Page Apps with React JS Ref: REACT JS ...

  7. [Code::Blocks] Install wxWidgets & openCV

    The open source, cross platform, free C++ IDE. Code::Blocks is a free C++ IDE built to meet the most ...

  8. 本人SW知识体系导航 - Programming menu

    将感悟心得记于此,重启程序员模式. js, py, c++, java, php 融汇之全栈系列 [Full-stack] 快速上手开发 - React [Full-stack] 状态管理技巧 - R ...

  9. React Route

    有幸你能看来我的这篇文章,这篇文章是继React后面写的Reactroute,所以你需要看看我前面整理的React笔记再来看Reactroute可能更容易 All the work we've don ...

随机推荐

  1. Codeforces Round #408 (Div. 2) 题解【ABCDE】

    A - Buying A House 题意:给你n个房间,妹子住在第m个房间,你有k块钱,你想买一个离妹子最近的房间.其中相邻的房间之间距离为10,a[i]=0表示已经被别人买了. 题解:扫一遍更新答 ...

  2. db2 事务日志

    曾经因为对DB2 的 NOT LOGGED INITIALLY 属性认识不足而吃了亏.当时需要往表中插入大量的数据,最初也没有考虑太多就使用了传统的insert 命令,由于数据量实在过于巨大,而且系统 ...

  3. ASP.NET Web API实现缓存的2种方式

    在ASP.NET Web API中实现缓存大致有2种思路.一种是通过ETag, 一种是通过类似ASP.NET MVC中的OutputCache. 通过ETag实现缓存 首先安装cachecow.ser ...

  4. Asp.Net Core 通过自定义中间件防止图片盗链的实例(转)

    一.原理 要实现防盗链,我们就必须先理解盗链的实现原理,提到防盗链的实现原理就不得不从HTTP协议说起,在HTTP协议中,有一个表头字段叫referer,采用URL的格式来表示从哪儿链接到当前的网页或 ...

  5. 临时和永久关闭Selinux

    临时关闭: [root@localhost ~]# getenforceEnforcing [root@localhost ~]# setenforce 0[root@localhost ~]# ge ...

  6. C语言100个经典的算法

    C语言的学习要从基础開始.这里是100个经典的算法-1C语言的学习要从基础開始,这里是100个经典的算法 题目:古典问题:有一对兔子,从出生后第3个月起每一个月都生一对兔子.小兔 子长到第三个月后每一 ...

  7. EntityFramework中常用的数据删除方式

    最近在学EF,目前了解到删除操作有三种方式, 第一,官方推荐的先查询数据,再根据查询的对象,删除对象. 这是第一种,官方推荐 第二,自己创建一个对象,然后附加,然后删除. 这是第二种 第三,自己创建对 ...

  8. JAVA 自定义注解在自动化测试中的使用

    在UI自动化测试中,相信很多人都喜欢用所谓的PO模式,其中的P,也就是page的意思,于是乎,在脚本里,或者在其它的page里,会要new很多的page对象,这样很麻烦,前面我们也讲到了注解的使用,很 ...

  9. 专访图书作者祁宇:C++11让程序更简洁、更现代、更强大

    日前CSDN采访了祁宇,请他解读C++11的新标准.C++的现状以及未来的发展前景. CSDN:怎么会想到编写<深入应用C++11:代码优化与工程级应用>这本书的?有没有什么故事可以分享下 ...

  10. 《软件测试自动化之道》读书笔记 之 基于Windows的UI测试

    <软件测试自动化之道>读书笔记 之 基于Windows的UI测试 2014-09-25 测试自动化程序的任务待测程序测试程序  启动待测程序  获得待测程序主窗体的句柄  获得有名字控件的 ...