## Simple App
### 實驗目的
1. 學會使用 Node 編寫簡單的前端應用。
### 操作步驟
(1)新建一個目錄
~~~
$ mkdir simple-app-demo
$ cd simple-app-demo
~~~
(2)在該目錄下,新建一個`package.json`文件。
~~~
$ npm init -y
~~~
`package.json`是項目的配置文件。
(3)安裝`jquery`和`webpack`這兩個模塊。
~~~
$ npm install -S jquery
$ npm install -S webpack
~~~
打開`package.json`文件,會發現`jquery`和`webpack`都加入了`dependencies`字段,并且帶有版本號。
(4)在項目根目錄下,新建一個網頁文件`index.html`。
~~~
<html>
<body>
<h1>Hello World</h1>
<script src="bundle.js"></script>
</body>
</html>
~~~
(5)在項目根目錄下,新建一個腳本文件`app.js`。
~~~
const $ = require('jquery');
$('h1').css({ color: 'red'});
~~~
上面代碼中,`require`方法是 Node 特有的模塊加載命令。
(6)打開`package.json`,在`scripts`字段里面,添加一行。
~~~
"scripts": {
"build": "webpack app.js bundle.js",
"test": "...."
},
~~~
(7) 在項目根目錄下,執行下面的命令,將腳本打包。
~~~
$ npm run build
~~~
執行完成,可以發現項目根目錄下,新生成了一個文件`bundle.js`。
(8)瀏覽器打開`index.html`,可以發現`Hello World`變成了紅色。
### 練習
1. 修改樣式,將標題變為藍色,然后重新編譯生成打包文件。
## REST API
### 實驗目的
1. 熟悉 REST API 的基本用法
### 操作步驟
(1) 命令行進入`rest-api-demo`目錄,執行下面的命令。
~~~
$ npm install -S json-server
~~~
(2) 在項目根目錄下,新建一個 JSON 文件`db.json`。
~~~
{
"posts": [
{ "id": 1, "title": "json-server", "author": "typicode" }
],
"comments": [
{ "id": 1, "body": "some comment", "postId": 1 }
],
"profile": { "name": "typicode" }
}
~~~
(3) 打開`package.json`,在`scripts`字段添加一行。
~~~
"scripts": {
"server": "json-server db.json",
"test": "..."
},
~~~
(4) 命令行下執行下面的命令,啟動服務。
~~~
$ npm run server
~~~
(5)打開 Chrome 瀏覽器的 Postman 應用。依次向`http://127.0.0.1:3000/posts`、`http://127.0.0.1:3000/posts/1`發出`GET`請求,查看結果。
(6)向`http://127.0.0.1:3000/comments`發出`POST`請求。注意,數據體`Body`要選擇`x-www-form-urlencoded`編碼,然后依次添加下面兩個字段。
~~~
body: "hello world"
postId: 1
~~~
發出該請求后,再向`http://127.0.0.1:3000/comments`發出`GET`請求,查看結果。
(7) 向`http://127.0.0.1:3000/comments/2`發出`PUT`請求,數據體`Body`要選擇`x-www-form-urlencoded`編碼,然后添加下面的字段。
~~~
body: "hello react"
~~~
發出該請求后,再向`http://127.0.0.1:3000/comments`發出`GET`請求,查看結果。
(8)向`http://127.0.0.1:3000/comments/2`發出`delete`請求。
發出該請求后,再向`http://127.0.0.1:3000/comments`發出`GET`請求,查看結果。
## Express
### 實驗目的
1. 學會 Express 搭建 Web 應用的基本用法。
### 操作步驟
(1)進入`demos/express-demo`目錄,命令行執行下面的命令,安裝依賴。
~~~
$ cd demos/express-demo
$ npm install
~~~
(2)打開`app1.js`,嘗試看懂這個腳本。
~~~
var express = require('express');
var app = express();
~~~
上面代碼調用`express`,生成一個 Web 應用的實例。
~~~
var router = express.Router();
router.get('/', function(req, res) {
res.send('<h1>Hello World</h1>');
});
app.use('/home', router);
~~~
上面代碼新建了一個路由對象,該對象指定訪問根路由(`/`)時,返回`Hello World`。然后,將該路由加載在`/home`路徑,也就是說,訪問`/home`會返回`Hello World`。
`router.get`方法的第二個參數是一個回調函數,當符合指定路由的請求進來,會被這個函數處理。該函數的兩個參數,`req`和`res`都是Express 內置的對象,分別表示用戶的請求和 Web 服務器的回應。`res.send`方法就表示服務器回應所送出的內容。
~~~
var port = process.env.PORT || 8080;
app.listen(port);
console.log('Magic happens on port ' + port);
~~~
上面代碼指定了外部訪問的端口,如果環境變量沒有指定,則端口默認為`8080`。最后兩行是啟動應用,并輸出一行提示文字。
(3)在命令行下,啟動這個應用。
~~~
$ node app1.js
~~~
瀏覽器訪問`localhost:8080/home`,看看是否輸出`Hello World`。
然后,命令行下按 Ctrl + C,退出這個進程。
(4)通過環境變量,自定義啟動端口。
假定我們指定必須啟動在`7070`端口,命令行可以這樣操作。
~~~
# Linux & Mac
$ PORT=7070 node app1.js
# windows
$ set PORT=7070
$ node app1.js
~~~
瀏覽器就可以訪問`localhost:7070/home`了。
然后,命令行下按 Ctrl + C,退出這個進程。
思考題:Node 應用能否直接在`80`端口啟動?
(5)打開`app2.js`,查看新增的那個路由。
~~~
router.get('/:name', function(req, res) {
res.send('<h1>Hello ' + req.params.name + '</h1>');
});
~~~
上面代碼新增了一個路由,這個路由的路徑是一個命名參數`:name`,可以從`req.params.name`拿到這個傳入的參數。
在命令行下,啟動這個應用。
~~~
$ node app2.js
~~~
瀏覽器訪問`localhost:8080/home/張三`,看看是否輸出`Hello 張三`。
然后,命令行下按 Ctrl + C,退出這個進程。
(6)打開`app3.js`,先查看頁面頭部新增的兩行代碼。
~~~
var express = require('express');
var app = express();
// 新增代碼...
var bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: true }));
// ...
~~~
上面代碼中,`body-parser`模塊的作用,是對`POST`、`PUT`、`DELETE`等 HTTP 方法的數據體進行解析。`app.use`用來將這個模塊加載到當前應用。有了這兩句,就可以處理`POST`、`PUT`、`DELETE`等請求了。
下面查看新增的那個路由。
~~~
router.post('/', function (req, res) {
var name = req.body.name;
res.json({message: 'Hello ' + name});
});
~~~
上面代碼表示,如果收到了`/`路徑(實際上是`/home`路徑)的`POST`請求,先從數據體拿到`name`字段,然后返回一段 JSON 信息。
在命令行下,啟動這個應用。
~~~
$ node app3.js
~~~
然后,在 Chrome 瀏覽器的 Postman 插件里面,向`http://127.0.0.1:8080/home`發出一個`POST`請求。數據體的編碼方法設為`x-www-form-urlencoded`,里面設置一個`name`字段,值可以隨便取,假定設為`Alice`。也就是說,發出這樣一個請求。
~~~
POST /home HTTP/1.1
Host: 127.0.0.1:8080
Content-Type: application/x-www-form-urlencoded
name=Alice
~~~
如果一切正常,服務器會返回一段 JSON 信息。
~~~
{
"message": "Hello Alice"
}
~~~
(7)打開`app4.js`,查看在所有路由之前新增的那個函數。
~~~
var router = express.Router();
// 新增的代碼
router.use(function(req, res, next) {
console.log('Thers is a requesting.');
next();
});
router.get('/', function(req, res) {
// ...
~~~
`router.use`的作用是加載一個函數。這個函數被稱為中間件,作用是在請求被路由匹配之前,先進行一些處理。上面這個中間件起到 logging 的作用,每收到一個請求,就在命令行輸出一條記錄。請特別注意,這個函數內部的`next()`,它代表下一個中間件,表示將處理過的請求傳遞給下一個中間件。這個例子只有一個中間件,就進入路由匹配處理(實際上,`bodyparser`、`router`本質都是中間件,整個 Express 的設計哲學就是不斷對 HTTP 請求加工,然后返回一個 HTTP 回應)。
### 練習
1. 請增加一個中間件,服務器每次收到用戶請求,會在服務器的控制臺打印出收到請求的時間。
2. URL 的查詢字符串,比如`localhost:8080?name=Alice`里面的`name`,可以用`req.query.name`拿到。請修改一個路由,使之可以收到查詢字符串,然后輸出`'Hello ' + req.query.name`。