前端那些事之node+express+koa學習

《搭建 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.ejscss

<!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.ejshtml

</body>
</html>

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

<% 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.ejsjquery

<% 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.ejsgit

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

輸入圖片說明

koa

相關文章
相關標籤/搜索