08、Node.js -Express框架 -RESTful API

Express 簡(jiǎn)介
Express 是一個(gè)簡(jiǎn)潔而靈活的 node.js Web應(yīng)用框架, 提供了一系列強(qiáng)大特性幫助你創(chuàng)建各種 Web 應(yīng)用,和豐富的 HTTP 工具。
使用 Express 可以快速地搭建一個(gè)完整功能的網(wǎng)站。
Express 框架核心特性:
可以設(shè)置中間件來(lái)響應(yīng) HTTP 請(qǐng)求。
定義了路由表用于執(zhí)行不同的 HTTP 請(qǐng)求動(dòng)作。
可以通過(guò)向模板傳遞參數(shù)來(lái)動(dòng)態(tài)渲染 HTML 頁(yè)面。
01、安裝 Express
安裝 Express 并將其保存到依賴列表中:

$ cnpm install express --save

以上命令會(huì)將 Express 框架安裝在當(dāng)前目錄的 node_modules 目錄中, node_modules 目錄下會(huì)自動(dòng)創(chuàng)建 express 目錄。以下幾個(gè)重要的模塊是需要與 express 框架一起安裝的:
body-parser - node.js 中間件,用于處理 JSON, Raw, Text 和 URL 編碼的數(shù)據(jù)。
cookie-parser - 這就是一個(gè)解析Cookie的工具。通過(guò)req.cookies可以取到傳過(guò)來(lái)的cookie,并把它們轉(zhuǎn)成對(duì)象。
multer - node.js 中間件,用于處理 enctype="multipart/form-data"(設(shè)置表單的MIME編碼)的表單數(shù)據(jù)。

$ cnpm install body-parser --save
$ cnpm install cookie-parser --save
$ cnpm install multer --save

安裝完后,我們可以查看下 express 使用的版本號(hào):

$ cnpm list express
/data/www/node
└── express@4.15.2  -> /Users/tianqixin/www/node/node_modules/.4.15.2@express

02、第一個(gè) Express 框架實(shí)例
接下來(lái)我們使用 Express 框架來(lái)輸出 "Hello World"。
以下實(shí)例中我們引入了 express 模塊,并在客戶端發(fā)起請(qǐng)求后,響應(yīng) "Hello World" 字符串。
創(chuàng)建 express_demo.js 文件,代碼如下所示:

//express_demo.js 文件
var express = require('express');
var app = express();
 
app.get('/', function (req, res) {
   res.send('Hello World');
})
 
var server = app.listen(8081, function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)
 
})

執(zhí)行以上代碼:

$ node express_demo.js 
應(yīng)用實(shí)例,訪問(wèn)地址為 http://0.0.0.0:8081

03、請(qǐng)求和響應(yīng)
Express 應(yīng)用使用回調(diào)函數(shù)的參數(shù): request 和 response 對(duì)象來(lái)處理請(qǐng)求和響應(yīng)的數(shù)據(jù)。

app.get('/', function (req, res) {
   // --
})

request 和 response 對(duì)象的具體介紹:
Request 對(duì)象 - request 對(duì)象表示 HTTP 請(qǐng)求,包含了請(qǐng)求查詢字符串,參數(shù),內(nèi)容,HTTP 頭部等屬性。常見(jiàn)屬性有:

req.app:當(dāng)callback為外部文件時(shí),用req.app訪問(wèn)express的實(shí)例
req.baseUrl:獲取路由當(dāng)前安裝的URL路徑
req.body / req.cookies:獲得「請(qǐng)求主體」/ Cookies
req.fresh / req.stale:判斷請(qǐng)求是否還「新鮮」
req.hostname / req.ip:獲取主機(jī)名和IP地址
req.originalUrl:獲取原始請(qǐng)求URL
req.params:獲取路由的parameters
req.path:獲取請(qǐng)求路徑
req.protocol:獲取協(xié)議類型
req.query:獲取URL的查詢參數(shù)串
req.route:獲取當(dāng)前匹配的路由
req.subdomains:獲取子域名
req.accepts():檢查可接受的請(qǐng)求的文檔類型
req.acceptsCharsets / req.acceptsEncodings / req.acceptsLanguages:返回指定字符集的第一個(gè)可接受字符編碼
req.get():獲取指定的HTTP請(qǐng)求頭
req.is():判斷請(qǐng)求頭Content-Type的MIME類型

Response 對(duì)象 - response 對(duì)象表示 HTTP 響應(yīng),即在接收到請(qǐng)求時(shí)向客戶端發(fā)送的 HTTP 響應(yīng)數(shù)據(jù)。常見(jiàn)屬性有:

res.app:同req.app一樣
res.append():追加指定HTTP頭
res.set()在res.append()后將重置之前設(shè)置的頭
res.cookie(name,value [,option]):設(shè)置Cookie
opition: domain / expires / httpOnly / maxAge / path / secure / signed
res.clearCookie():清除Cookie
res.download():傳送指定路徑的文件
res.get():返回指定的HTTP頭
res.json():傳送JSON響應(yīng)
res.jsonp():傳送JSONP響應(yīng)
res.location():只設(shè)置響應(yīng)的Location HTTP頭,不設(shè)置狀態(tài)碼或者close response
res.redirect():設(shè)置響應(yīng)的Location HTTP頭,并且設(shè)置狀態(tài)碼302
res.send():傳送HTTP響應(yīng)
res.sendFile(path [,options] [,fn]):傳送指定路徑的文件 -會(huì)自動(dòng)根據(jù)文件extension設(shè)定Content-Type
res.set():設(shè)置HTTP頭,傳入object可以一次設(shè)置多個(gè)頭
res.status():設(shè)置HTTP狀態(tài)碼
res.type():設(shè)置Content-Type的MIME類型

04、路由
我們已經(jīng)了解了 HTTP 請(qǐng)求的基本應(yīng)用,而路由決定了由誰(shuí)(指定腳本)去響應(yīng)客戶端請(qǐng)求。
在HTTP請(qǐng)求中,我們可以通過(guò)路由提取出請(qǐng)求的URL以及GET/POST參數(shù)。
接下來(lái)我們擴(kuò)展 Hello World,添加一些功能來(lái)處理更多類型的 HTTP 請(qǐng)求。
創(chuàng)建 express_demo2.js 文件,代碼如下所示:

var express = require('express');
var app = express();
 
//  主頁(yè)輸出 "Hello World"
app.get('/', function (req, res) {
   console.log("主頁(yè) GET 請(qǐng)求");
   res.send('Hello GET');
})
 
 
//  POST 請(qǐng)求
app.post('/', function (req, res) {
   console.log("主頁(yè) POST 請(qǐng)求");
   res.send('Hello POST');
})
 
//  /del_user 頁(yè)面響應(yīng)
app.get('/del_user', function (req, res) {
   console.log("/del_user 響應(yīng) DELETE 請(qǐng)求");
   res.send('刪除頁(yè)面');
})
 
//  /list_user 頁(yè)面 GET 請(qǐng)求
app.get('/list_user', function (req, res) {
   console.log("/list_user GET 請(qǐng)求");
   res.send('用戶列表頁(yè)面');
})
 
// 對(duì)頁(yè)面 abcd, abxcd, ab123cd, 等響應(yīng) GET 請(qǐng)求
app.get('/ab*cd', function(req, res) {   
   console.log("/ab*cd GET 請(qǐng)求");
   res.send('正則匹配');
})
 
 
var server = app.listen(8081, function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)
 
})

執(zhí)行以上代碼:

$ node express_demo2.js 
應(yīng)用實(shí)例,訪問(wèn)地址為 http://0.0.0.0:8081

05、靜態(tài)文件
Express 提供了內(nèi)置的中間件 express.static 來(lái)設(shè)置靜態(tài)文件如:圖片, CSS, JavaScript 等。
你可以使用 express.static 中間件來(lái)設(shè)置靜態(tài)文件路徑。例如,如果你將圖片, CSS, JavaScript 文件放在 public 目錄下,你可以這么寫:

app.use(express.static('public'));

我們可以到 public/images 目錄下放些圖片,如下所示:

node_modules
server.js
public/
public/images
public/images/logo.png

讓我們?cè)傩薷南?"Hello World" 應(yīng)用添加處理靜態(tài)文件的功能。
創(chuàng)建 express_demo3.js 文件,代碼如下所示:

var express = require('express');
var app = express();
 
app.use(express.static('public'));
 
app.get('/', function (req, res) {
   res.send('Hello World');
})
 
var server = app.listen(8081, function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)
 
})

結(jié)果:

$ node express_demo3.js 
應(yīng)用實(shí)例,訪問(wèn)地址為 http://0.0.0.0:8081

06、GET 方法
以下實(shí)例演示了在表單中通過(guò) GET 方法提交兩個(gè)參數(shù),我們可以使用 server.js 文件內(nèi)的 process_get 路由器來(lái)處理輸入
index.html文件

<html>
<body>
<form action="http://127.0.0.1:8081/process_get" method="GET">
First Name: <input type="text" name="first_name">  <br>
 
Last Name: <input type="text" name="last_name">
<input type="submit" value="Submit">
</form>
</body>
</html>

server.js

var express = require('express');
var app = express();
 
app.use(express.static('public'));
 
app.get('/index.htm', function (req, res) {
   res.sendFile( __dirname + "/" + "index.htm" );
})
 
app.get('/process_get', function (req, res) {
 
   // 輸出 JSON 格式
   var response = {
       "first_name":req.query.first_name,
       "last_name":req.query.last_name
   };
   console.log(response);
   res.end(JSON.stringify(response));
})
 
var server = app.listen(8081, function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)
 
})

執(zhí)行以上代碼:

node server.js 
應(yīng)用實(shí)例,訪問(wèn)地址為 http://0.0.0.0:8081

07、POST 方法
以下實(shí)例演示了在表單中通過(guò) POST 方法提交兩個(gè)參數(shù),我們可以使用 server.js 文件內(nèi)的 process_post 路由器來(lái)處理輸入:
index.html

<html>
<body>
<form action="http://127.0.0.1:8081/process_post" method="POST">
First Name: <input type="text" name="first_name">  <br>
 
Last Name: <input type="text" name="last_name">
<input type="submit" value="Submit">
</form>
</body>
</html>

server.js

var express = require('express');
var app = express();
var bodyParser = require('body-parser');
 
// 創(chuàng)建 application/x-www-form-urlencoded 編碼解析
var urlencodedParser = bodyParser.urlencoded({ extended: false })
 
app.use(express.static('public'));
 
app.get('/index.htm', function (req, res) {
   res.sendFile( __dirname + "/" + "index.htm" );
})
 
app.post('/process_post', urlencodedParser, function (req, res) {
 
   // 輸出 JSON 格式
   var response = {
       "first_name":req.body.first_name,
       "last_name":req.body.last_name
   };
   console.log(response);
   res.end(JSON.stringify(response));
})
 
var server = app.listen(8081, function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)
 
})

執(zhí)行以上代碼:

$ node server.js
應(yīng)用實(shí)例,訪問(wèn)地址為 http://0.0.0.0:8081

08、文件上傳
以下我們創(chuàng)建一個(gè)用于上傳文件的表單,使用 POST 方法,表單 enctype 屬性設(shè)置為 multipart/form-data。

<html>
<head>
<title>文件上傳表單</title>
</head>
<body>
<h3>文件上傳:</h3>
選擇一個(gè)文件上傳: <br />
<form action="/file_upload" method="post" enctype="multipart/form-data">
<input type="file" name="image" size="50" />
<br />
<input type="submit" value="上傳文件" />
</form>
</body>
</html>

server.js

<pre>
var express = require('express');
var app = express();
var fs = require("fs");
 
var bodyParser = require('body-parser');
var multer  = require('multer');
 
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: false }));
app.use(multer({ dest: '/tmp/'}).array('image'));
 
app.get('/index.htm', function (req, res) {
   res.sendFile( __dirname + "/" + "index.htm" );
})
 
app.post('/file_upload', function (req, res) {
 
   console.log(req.files[0]);  // 上傳的文件信息
 
   var des_file = __dirname + "/" + req.files[0].originalname;
   fs.readFile( req.files[0].path, function (err, data) {
        fs.writeFile(des_file, data, function (err) {
         if( err ){
              console.log( err );
         }else{
               response = {
                   message:'File uploaded successfully', 
                   filename:req.files[0].originalname
              };
          }
          console.log( response );
          res.end( JSON.stringify( response ) );
       });
   });
})
 
var server = app.listen(8081, function () {
 
  var host = server.address().address
  var port = server.address().port
 
  console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)
 
})

09、Cookie 管理
我們可以使用中間件向 Node.js 服務(wù)器發(fā)送 cookie 信息,以下代碼輸出了客戶端發(fā)送的 cookie 信息:

// express_cookie.js 文件
var express      = require('express')
var cookieParser = require('cookie-parser')
 
var app = express()
app.use(cookieParser())
 
app.get('/', function(req, res) {
  console.log("Cookies: ", req.cookies)
})
 
app.listen(8081)

------------------------------------------------RESTful API-----------------------------------------------------
什么是 REST?
REST即表述性狀態(tài)傳遞(英文:Representational State Transfer,簡(jiǎn)稱REST)是Roy Fielding博士在2000年他的博士論文中提出來(lái)的一種軟件架構(gòu)風(fēng)格。
表述性狀態(tài)轉(zhuǎn)移是一組架構(gòu)約束條件和原則。滿足這些約束條件和原則的應(yīng)用程序或設(shè)計(jì)就是RESTful。需要注意的是,REST是設(shè)計(jì)風(fēng)格而不是標(biāo)準(zhǔn)。REST通?;谑褂肏TTP,URI,和XML(標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言下的一個(gè)子集)以及HTML(標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言下的一個(gè)應(yīng)用)這些現(xiàn)有的廣泛流行的協(xié)議和標(biāo)準(zhǔn)。REST 通常使用 JSON 數(shù)據(jù)格式。
HTTP 方法
以下為 REST 基本架構(gòu)的四個(gè)方法:
GET - 用于獲取數(shù)據(jù)。
PUT - 用于更新或添加數(shù)據(jù)。
DELETE - 用于刪除數(shù)據(jù)。
POST - 用于添加數(shù)據(jù)。
01、RESTful Web Services
Web service是一個(gè)平臺(tái)獨(dú)立的,低耦合的,自包含的、基于可編程的web的應(yīng)用程序,可使用開(kāi)放的XML(標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言下的一個(gè)子集)標(biāo)準(zhǔn)來(lái)描述、發(fā)布、發(fā)現(xiàn)、協(xié)調(diào)和配置這些應(yīng)用程序,用于開(kāi)發(fā)分布式的互操作的應(yīng)用程序。
基于 REST 架構(gòu)的 Web Services 即是 RESTful。
由于輕量級(jí)以及通過(guò) HTTP 直接傳輸數(shù)據(jù)的特性,Web 服務(wù)的 RESTful 方法已經(jīng)成為最常見(jiàn)的替代方法??梢允褂酶鞣N語(yǔ)言(比如 Java 程序、Perl、Ruby、Python、PHP 和 Javascript[包括 Ajax])實(shí)現(xiàn)客戶端。
RESTful Web 服務(wù)通常可以通過(guò)自動(dòng)客戶端或代表用戶的應(yīng)用程序訪問(wèn)。但是,這種服務(wù)的簡(jiǎn)便性讓用戶能夠與之直接交互,使用它們的 Web 瀏覽器構(gòu)建一個(gè) GET URL 并讀取返回的內(nèi)容。
更多介紹,可以查看:RESTful 架構(gòu)詳解
02、創(chuàng)建 RESTful
首先,創(chuàng)建一個(gè) json 數(shù)據(jù)資源文件 users.json,內(nèi)容如下:

{
   "user1" : {
      "name" : "mahesh",
      "password" : "password1",
      "profession" : "teacher",
      "id": 1
   },
   "user2" : {
      "name" : "suresh",
      "password" : "password2",
      "profession" : "librarian",
      "id": 2
   },
   "user3" : {
      "name" : "ramesh",
      "password" : "password3",
      "profession" : "clerk",
      "id": 3
   }
}

基于以上數(shù)據(jù),我們創(chuàng)建以下 RESTful API:
序號(hào) URI HTTP 方法 發(fā)送內(nèi)容 結(jié)果

1   listUsers   GET 空   顯示所有用戶列表
2   addUser POST    JSON 字符串    添加新用戶
3   deleteUser  DELETE  JSON 字符串    刪除用戶
4   :id GET 空   顯示用戶詳細(xì)信息

03、獲取用戶列表:
以下代碼,我們創(chuàng)建了 RESTful API listUsers,用于讀取用戶的信息列表, server.js 文件代碼如下所示:

var express = require('express');
var app = express();
var fs = require("fs");

app.get('/listUsers', function (req, res) {
   fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
       console.log( data );
       res.end( data );
   });
})

var server = app.listen(8081, function () {

  var host = server.address().address
  var port = server.address().port

  console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

接下來(lái)執(zhí)行以下命令:

$ node server.js 
應(yīng)用實(shí)例,訪問(wèn)地址為 http://0.0.0.0:8081

在瀏覽器中訪問(wèn) http://127.0.0.1:8081/listUsers,結(jié)果如下所示:

{
   "user1" : {
      "name" : "mahesh",
      "password" : "password1",
      "profession" : "teacher",
      "id": 1
   },
   "user2" : {
      "name" : "suresh",
      "password" : "password2",
      "profession" : "librarian",
      "id": 2
   },
   "user3" : {
      "name" : "ramesh",
      "password" : "password3",
      "profession" : "clerk",
      "id": 3
   }
}

04、添加用戶
以下代碼,我們創(chuàng)建了 RESTful API addUser, 用于添加新的用戶數(shù)據(jù),server.js 文件代碼如下所示:

var express = require('express');
var app = express();
var fs = require("fs");

//添加的新用戶數(shù)據(jù)
var user = {
   "user4" : {
      "name" : "mohit",
      "password" : "password4",
      "profession" : "teacher",
      "id": 4
   }
}

app.get('/addUser', function (req, res) {
   // 讀取已存在的數(shù)據(jù)
   fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
       data = JSON.parse( data );
       data["user4"] = user["user4"];
       console.log( data );
       res.end( JSON.stringify(data));
   });
})

var server = app.listen(8081, function () {

  var host = server.address().address
  var port = server.address().port
  console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

接下來(lái)執(zhí)行以下命令:

$ node server.js 
應(yīng)用實(shí)例,訪問(wèn)地址為 http://0.0.0.0:8081

在瀏覽器中訪問(wèn) http://127.0.0.1:8081/addUser,結(jié)果如下所示:

{ user1:
   { name: 'mahesh',
     password: 'password1',
     profession: 'teacher',
     id: 1 },
  user2:
   { name: 'suresh',
     password: 'password2',
     profession: 'librarian',
     id: 2 },
  user3:
   { name: 'ramesh',
     password: 'password3',
     profession: 'clerk',
     id: 3 },
  user4:
   { name: 'mohit',
     password: 'password4',
     profession: 'teacher',
     id: 4 } 
}

05、顯示用戶詳情
以下代碼,我們創(chuàng)建了 RESTful API :id(用戶id), 用于讀取指定用戶的詳細(xì)信息,server.js 文件代碼如下所示:

var express = require('express');
var app = express();
var fs = require("fs");

app.get('/:id', function (req, res) {
   // 首先我們讀取已存在的用戶
   fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
       data = JSON.parse( data );
       var user = data["user" + req.params.id] 
       console.log( user );
       res.end( JSON.stringify(user));
   });
})

var server = app.listen(8081, function () {

  var host = server.address().address
  var port = server.address().port
  console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

接下來(lái)執(zhí)行以下命令:

$ node server.js 
應(yīng)用實(shí)例,訪問(wèn)地址為 http://0.0.0.0:8081

在瀏覽器中訪問(wèn) http://127.0.0.1:8081/2,結(jié)果如下所示:

{
   "name":"suresh",
   "password":"password2",
   "profession":"librarian",
   "id":2
}

06、刪除用戶
以下代碼,我們創(chuàng)建了 RESTful API deleteUser, 用于刪除指定用戶的詳細(xì)信息,以下實(shí)例中,用戶 id 為 2,server.js 文件代碼如下所示:

var express = require('express');
var app = express();
var fs = require("fs");

var id = 2;

app.get('/deleteUser', function (req, res) {

   // First read existing users.
   fs.readFile( __dirname + "/" + "users.json", 'utf8', function (err, data) {
       data = JSON.parse( data );
       delete data["user" + 2];
       
       console.log( data );
       res.end( JSON.stringify(data));
   });
})

var server = app.listen(8081, function () {

  var host = server.address().address
  var port = server.address().port
  console.log("應(yīng)用實(shí)例,訪問(wèn)地址為 http://%s:%s", host, port)

})

接下來(lái)執(zhí)行以下命令:

$ node server.js 
應(yīng)用實(shí)例,訪問(wèn)地址為 http://0.0.0.0:8081

在瀏覽器中訪問(wèn) http://127.0.0.1:8081/deleteUser,結(jié)果如下所示:

{ user1:
   { name: 'mahesh',
     password: 'password1',
     profession: 'teacher',
     id: 1 },
  user3:
   { name: 'ramesh',
     password: 'password3',
     profession: 'clerk',
     id: 3 } 
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,569評(píng)論 19 139
  • Express 簡(jiǎn)介 Express 是一個(gè)簡(jiǎn)潔而靈活的 node.js Web應(yīng)用框架, 提供了一系列強(qiáng)大特性幫...
    保川閱讀 2,080評(píng)論 0 24
  • Express是Node社區(qū)里的超級(jí)明星,他的作者TJ Holowaychuk也因此成為了社區(qū)里大紅大紫的開(kāi)發(fā)者。...
    2MuchT閱讀 3,132評(píng)論 1 30
  • 3109103-陳求忠總結(jié),《2017年11月29號(hào)》(連續(xù)總結(jié)第3天)輔導(dǎo)員-海燕姐 一:今天完成目標(biāo) 1抄寫p...
    進(jìn)階階段閱讀 195評(píng)論 0 0

友情鏈接更多精彩內(nèi)容