文档章节

前端那些事之node+express+koa学习

上官清偌
 上官清偌
发布于 2017/10/31 09:45
字数 2860
阅读 58
收藏 0

《搭建 Node.js 开发环境》

  • windows 环境
  • 直接从 github clone nvmw 到本地, 这里假设大家都使用 d:\git 目录存放 git 项目
$ d:
$ cd git
$ git clone https://github.com/cnpm/nvmw.git
  • 设置 d:\git\nvmw 目录到你的 PATH 环境变量中:
set "PATH=d:\git\nvmw;%PATH%"
  • 重新打开你的终端, 输入 nvmw
$ nvmw

Usage:
  nvmw help                    Show this message
  nvmw install [version]       Download and install a [version]
  nvmw uninstall [version]     Uninstall a [version]
  nvmw use [version]           Modify PATH to use [version]
  nvmw ls                      List installed versions

Example:
  nvmw install v0.6.0          Install a specific version number
  nvmw use v0.6.0              Use the specific version
  • 通过 nvmw 安装任意版本的 node
$ nvmw install 0.12.0

使用 cnpm 加速 npm

  • 同理 nvm , npm 默认是从国外的源获取和下载包信息, 比较慢. 可以通过简单的 ---registry 参数, 使用国内的镜像 http://registry.npm.taobao.org :
例如:下载koa
$ npm install koa --registry=http://registry.npm.taobao.org
  • 但是毕竟镜像跟官方的 npm 源还是会有一个同步时间差异, 目前 cnpm 的默认同步时间间隔是 10 分钟. 如果你是模块发布者, 或者你想马上同步一个模块, 那么推荐你安装 cnpm cli:
$ npm install cnpm -g --registry=http://registry.npm.taobao.org

express-generator快速搭建node工程项目

  • 安装:npm install express-generator -g
  • 创建工程名称:
express server
  • 运行
cd server
node bin/www
  • 访问
http://localhost:3000/

《一个最简单的 express 应用》

var express = require('express');
// 调用 express 实例,它是一个函数,不带参数调用时,会返回一个 express 实例,将这个变量赋予 app 变量。
var app = express();

// app 本身有很多方法,其中包括最常用的 get、post、put/patch、delete,在这里我们调用其中的 get 方法,为我们的 `/` 路径指定一个 handler 函数。
// 这个 handler 函数会接收 req 和 res 两个对象,他们分别是请求的 request 和 response。
// request 中包含了浏览器传来的各种信息,比如 query 啊,body 啊,headers 啊之类的,都可以通过 req 对象访问到。
// res 对象,我们一般不从里面取信息,而是通过它来定制我们向浏览器输出的信息,比如 header 信息,比如想要向浏览器输出的内容。这里我们调用了它的 #send 方法,向浏览器输出一个字符串。
app.get('/', function (req, res) {
  res.send('Hello World');
});

// 定义好我们 app 的行为之后,让它监听本地的 3000 端口。这里的第二个函数是个回调函数,会在 listen 动作成功后执行,我们这里执行了一个命令行输出操作,告诉我们监听动作已完成。
app.listen(3000, function () {
  console.log('app is listening at port 3000');
});

使用外部模块(utilitymd5加密用的)

  • 知识点:
    • 1.学习 req.query 的用法
    • 2.学习建立 package.json 来管理 Node.js 项目
  • 步骤:
    • 新建文件 test
    • cd test
    • npm init
    • npm install express utility --save
  • 新建app.js
// 引入依赖
var express = require('express');
var utility = require('utility');

// 建立 express 实例
var app = express();

app.get('/', function (req, res) {
  // 从 req.query 中取出我们的 q 参数。
  // 如果是 post 传来的 body 数据,则是在 req.body 里面,不过 express 默认不处理 body 中的信息,需要引入 https://github.com/expressjs/body-parser 这个中间件才会处理,这个后面会讲到。
  // 如果分不清什么是 query,什么是 body 的话,那就需要补一下 http 的知识了
  var q = req.query.q;

  // 调用 utility.md5 方法,得到 md5 之后的值
  // 之所以使用 utility 这个库来生成 md5 值,其实只是习惯问题。每个人都有自己习惯的技术堆栈,
  // 我刚入职阿里的时候跟着苏千和朴灵混,所以也混到了不少他们的技术堆栈,仅此而已。
  // utility 的 github 地址:https://github.com/node-modules/utility
  // 里面定义了很多常用且比较杂的辅助方法,可以去看看
  var md5Value = utility.md5(q);

  res.send(md5Value);
});

app.listen(3000, function (req, res) {
  console.log('app is running at port 3000');
});
  • 运行node app.js
  • 运行结果:

输入图片说明

《使用 superagent 与 cheerio 完成简单爬虫》

  • 知识点:
    • 1.学习使用 superagent 抓取网页
    • 2.学习使用 cheerio 分析网页
  • superagent(http://visionmedia.github.io/superagent/ ) 是个 http 方面的库,可以发起 get 或 post 请求。
  • cheerio(https://github.com/cheeriojs/cheerio ) 大家可以理解成一个 Node.js 版的 jquery,用来从网页中以 css selector 取数据,使用方式跟 jquery 一样一样的。
  • 步骤:
    • 新建文件 test
    • cd test
    • npm init
    • npm install express superagent cheerio --save
  • 新建 app.js
const express = require('express');
const superagent = require('superagent');
const cheerio = require('cheerio');
const app = express();

app.get('/', function (req, res, next) {
    // 用 superagent 去抓取 https://cnodejs.org/ 的内容
    superagent.get('https://cnodejs.org/')
        .end(function (err, sres) {
            // 常规的错误处理
            if (err) {
                return next(err);
            }
            // sres.text 里面存储着网页的 html 内容,将它传给 cheerio.load 之后
            // 就可以得到一个实现了 jquery 接口的变量,我们习惯性地将它命名为 `$`
            // 剩下就都是 jquery 的内容了
            var $ = cheerio.load(sres.text);
            var items = [];
            $('#topic_list .topic_title').each(function (idx, element) {
                var $element = $(element);
                items.push({
                    title: $element.attr('title'),
                    href: $element.attr('href')
                });
            });

            res.send(items);
        });
});
app.listen(3000, function () {
    console.log('app is listening at port 3000');
});
  • 运行结果:

输入图片说明

MORGAN:日志记录中间件

  • Morgan 是一个功能非常强大的日志中间件。它能对用户的行为和请求时间进行记录。而这对于分析异常行为和可能的站点崩溃来说非常有用。大多数时候 Morgan 也是 Express 中日志中间件的首选。
  • 使用命令 npm install morgan --save
  • index.js
const express = require('express');
const logger = require('morgan');
const app = express();
app.use(logger('short'));
app.use((req,res)=>{
    res.writeHead(200, {"Content-Type": "text/plain"});
    res.end('vb, vb')
})
app.listen(3000,()=>{
    console.log('兼听成功');

})
  • 运行node index.js

输入图片说明

Express 的静态文件中间件

  • 通过网络发送静态文件对 Web 应用来说是一个常见的需求场景。这些资源通常包括图片资源、CSS 文件以及静态 HTML 文件。但是一个简单的文件发送行为其实代码量很大,因为需要检查大量的边界情况以及性能问题的考量。而 Express 内置的 express.static 模块能最大程度简化工作。
  • 假设现在需要对 public 文件夹提供文件服务,只需通过静态文件中间件我们就能极大压缩代码量:
const express = require('express');
const path = require('path');
const app = express();
const pulbicPath = path.resolve(__dirname, "public");

app.use(express.static(pulbicPath));
app.use((req,res) =>{
    res.writeHead(200, { "Content-Type": "text/plain" });
    res.end("Looks like you didn't find a static file.");
})
app.listen(3000,()=>{
    console.log("兼听成功");

})
  • 现在,任何在 public 目录下的静态文件都能直接请求了,所以你可以将所有需要的文件的放在该目录下。如果 public 文件夹中没有任何匹配的文件存在,它将继续执行下一个中间件并响应一段 没有匹配的文件信息。

为什么使用 path.resolve ?

  • 之所以不直接使用 /public 是因为 Mac 和 Linux 中目录为 /public 而 Windows 使用万恶的反斜杠 public 。path.resolve 就是用来解决多平台目录路径问题。

更多中间件

  • connect-ratelimit:可以让你控制每小时的连接数。如果某人向服务发起大量请求,那么可以直接返回错误停止处理这些请求
  • helmet:可以添加 HTTP 头部信息来应对一些网络攻击
  • cookie-parses:用于解析浏览器中的 cookie 信息
  • response-time:通过发送 X-Response-Time 信息,让你能够更好的调试应用的性能

路由

  • 路由是一种将 URL 和 HTTP 方法映射到特定处理回调函数的技术
const express = require('express');
const logger = require('morgan');
const path = require('path');
const app = express();
//获取输出日志信息
app.use(logger('short'));
// 所有的请求通过这个中间件,如果没有文件被找到的话会继续前进
const publicPath = path.resolve(__dirname, "public");
app.use(express.static(publicPath));
// 当请求根目录的时候被调用
app.get("/", (req, res) => {
    res.end("home");
});

app.get("/about", (req, res) => {
    res.end("about");
});

app.get("/other", (req, res) => {
    res.end("ohter")
})

//除了固定路由形式外,它还可以匹配更复杂的路由(使用正则等方式):

app.get("/home/:other", (req, res) => {
    // :other 并不是固定住,它表示 URL 中传递过来的名字
    res.end("hello"+req.params.other)
})


// 前面都不匹配,则路由错误。返回 404 页面
app.use((req, res) => {
    res.statusCode = 404;
    res.end("404");
})

app.listen(3000, () => {
    console.log("suceess!");
});


扩展 request 和 response

  • Express 在原来基础上对 request 和 response 对象进行了功能扩展。
  • 其中一部分response扩展:
  • 原生 Node 中并没有重定向 redirect 方法
设置重定向
app.get("/my", (req, res) => {
    res.redirect("/home/my");
    res.end("my=>redirect");
})
  • 文件的发送
response.sendFile("path/to/cool_song.mp3")
  • 其中一部分request扩展
  • request.ip 获取发送请求的机器 IP 地址或者通过 request.get 获取 HTTP 头部
var express = require("express");
var app = express();

var EVIL_IP = "123.45.67.89";

app.use(function(request, response, next) {
    if (request.ip === EVIL_IP) {
        response.status(401).send("Not allowed!");
    } else {
        next();
    }
});

  • 这里使用到了 req.ip 以及 res.status() 和 res.send() ,而这些方法全都来自于 Express 的拓展

视图

  • Express 模版引擎,例如: EJS、Handlebars、Pug。
  • 安装 EJS npm install ejs --save
  • 步骤
    • 创建views 文件夹,在views文件夹中创建一个 index.ejs 文件
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Hello, world!</title>
</head>
<body>
    <%= message %>
</body>
</html>
  • 在app.js 中写入
const express = require('express')
const path = require('path')
const app = express();
// 告诉 Express 你的视图存在于一个名为 views 的文件夹中
app.set("views", path.resolve(__dirname, "views"))


// 告诉 Express 你将使用EJS模板引擎
app.set("view engine", "ejs")

app.get("/", (req, res) => {
    res.render('index', {
        message: "hello ejs"
    })
})

app.listen(3000, () => {
    console.log("susscess");

})

  • 执行node app.js :结果在页面中显示:hello ejs

ejs - Demo(一个简易的留言板)

  • 步骤: 1 npm init (生成package.json文件,把scripts设置成npm start)
{
  "name": "le",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "node app"
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
  
  }
}
  1. 下载npm install express morgan body-parser ejs --save
  2. app.js
const express = require("express");
const path = require("path");
const logger = require("morgan");
const bodyParser = require("body-parser");

const app = express();

// 告诉 Express 你的视图存在于一个名为 views 的文件夹中
app.set("views", path.resolve(__dirname, "views"))
// 告诉 Express 你将使用EJS模板引擎
app.set("view engine", "ejs")

//设置留言的全局变量
const entries = [];
app.locals.entries = entries;

//使用morgan 进行日志记录
app.use(logger("dev"));

// 设置用户表单提交动作信息的中间件,所有信息会保存在 req.body 里
app.use(bodyParser.urlencoded({extended: false}));

// 当访问了网站根目录,就渲染主页(位于views/index.ejs)
app.get("/", (req, res) => {
    res.render("index");
})

// 渲染“新留言”页面(位于views/index.ejs)当get访问这个URL的时候
app.get("/new-entry", (req, res) => {
    res.render("new-entry");
})

// POST 动作进行留言新建的路由处理
app.post("/new-entry", (req, res) => {
    // 如果用户提交的表单没有标题或者内容,则返回一个 400 的错误
    if(!req.body.title || !req.body.body){
        res.status(400).send("Entries must have a title and a body.");
        return;
    }
    // 添加新留言到 entries 中
    entries.push({
        title: req.body.title,
        content: req.body.body,
        published: new Date()
    })
    // 重定向到主页来查看你的新条目
    res.redirect("/");
})

// 渲染404页面,因为你请求了未知资源
app.use((req, res) => {
    res.status(404).render("404");
})

app.listen(3000, () => {
    console.log("susscess!");
})

4.新建文件夹view,在view中新建header.ejs

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Express Demo</title>
    <link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
</head>
<body class="container">
<h1>
    Express Guestbook
    <a href="/new-entry" class="btn btn-primary pull-right">
        Write in the guestbook
    </a>
</h1>

5.在views文件中新建footer.ejs

</body>
</html>

6.在views文件中新建index.ejs

<% include header.ejs %>

<% if (entries.length) { %>
<% entries.forEach(function(entry) { %>
<div class="panel panel-default">
    <div class="panel-heading">
        <div class="text-muted pull-right">
            <%= entry.published %>
        </div>
        <%= entry.title %>
    </div>
    <div class="panel-body">
        <%= entry.body %>
    </div>
</div>
<% }) %>
<% } else { %>
    No entries! <a href="/new-entry">Add one!</a>
<% } %>

<% include footer.ejs %>

7.在views文件中新建new-entry.ejs

<% include header %>
<h2>Write a new entry</h2>
<form method="post" role="form">
    <div class="form-group">
        <label for="title">Title</label>
        <input type="text" class="form-control" id="title" name="title" placeholder="Entry title" required>
    </div>
    <div class="form-group">
        <label for="content">Entry text</label>
        <textarea class="form-control" id="body" name="body" placeholder="Love Express! It's a great tool for building websites." rows="3" required></textarea>
    </div>
    <div class="form-group">
        <input type="submit" value="Post entry" class="btn btn-primary">
    </div>
</form>
<% include footer %>

8.在views文件中新建404.ejs

<%include header.ejs%>
<h2>404! Page not found.</h2>
<%include footer.ejs%>
  1. 运行 npm start
  2. 运行结果

输入图片说明

koa

© 著作权归作者所有

上官清偌
粉丝 11
博文 87
码字总数 123753
作品 0
浦东
程序员
私信 提问
AI 时代,爱学习的程序员都关注了这些…

这篇文章推荐了包括技术、设计、极客相关的热门公众号。

p5deyt322jacs
2018/01/07
0
0
趣图:大前端解放全世界指日可待

(给程序员的那些事加星标,每天看趣图) 前端工程师口若悬河的演示完所谓的全栈开发框架, 大前端解放全世界指日可待,引得众人鼓掌.... ↓↓↓ 往期趣图(点击下方图片可跳转阅读) 关注「...

程序员的那些事_
2018/11/20
0
0
程序员软实力养成记

摘要:我认为一个好的序员不仅要有过硬的编码能力,还要会在职场上为人处世,俗话说的好:“先做人,后做事”。现在快节奏的社会中,职场如战场,我们如何在万千分之一中找到属于自己位置 一、...

技术金三胖
2018/01/13
0
0
程序员的软实力如何养成

摘要:我认为一个好的序员不仅要有过硬的编码能力,还要会在职场上为人处世,俗话说的好:“先做人,后做事”。现在快节奏的社会中,职场如战场,我们如何在万千分之一中找到属于自己位置 一、...

weixin_金三胖_0
2018/01/12
0
0
趣图:我就改一个参数,前端不会崩的,后端更不可能崩

(给程序员的那些事加星标,每天看趣图) 我就改一个参数, 前端不会崩的,后端更不可能崩 ↓↓↓ 往期趣图(点击下方图片可跳转阅读) 关注「程序员的那些事」加星标,每天看趣图 (商务合作...

程序员的那些事_
2018/12/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

分布式场景下如何保证消息队列实现最终一致性

考虑一个分布式场景中一个常见的场景:服务A执行某个数据库操作成功后,会发送一条消息到消息队列,现在希望只有数据库操作执行成功才发送这条消息。下面是一些常见的作法: 1. 先执行数据库...

中关村的老男孩
13分钟前
0
0
招银网络面试题、考点、知识点总结(Java岗)

java基础 全是基础不用多说肯定考的多,尤其是招银 OOP特性/java语言特性:封装、继承、多态 多态具体的表现:多态应用举例、如何调用父类方法(super)、重写和重载(重写父类方法的规则、构...

戎码益深
18分钟前
0
0
Mybatis深入源码分析之SQLSession一级缓存原理分析

源码分析图

须臾之余
21分钟前
0
0
成年人社交中的10个潜规则

前阵子我建议大家有空的时候,一定要去看《红楼梦》这本书。 原因就是从这本书,可以学习到很多很多人情世故,人情世故在学校里,老师几乎都不会教,所以我们只能靠自己去学。 只有自己去学了...

ZhangLG
23分钟前
1
0
在PyCharm中使用Pylint

简介 pylint是一个用于检查python代码中的错误,尝试强制执行编码标准的工具。它还可以查找某些类型错误,可以建议如何重构特定块的建议,并可以向您提供有关代码复杂性的详细信息。 官网:w...

哼_哼
24分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部