この記事では、主に Express ミドルウェアの仕組みと実装原理を紹介します。編集者がそれを紹介し、参考にさせていただきます。エディターをフォローして見てみましょう
はじめに
ミドルウェアメカニズムを使用すると、特定のプロセスに処理ステップを追加することができ、それによってプロセスの入力または出力に影響を与えたり、中間効果、ステータス、またはこのプロセスを傍受します。ミドルウェアのメカニズムは Tomcat のフィルターに似ており、どちらも責任連鎖モデルの特定の実装です。
エクスプレスミドルウェアの使用例
let express = require('express') let app = express() //解析request 的body app.use(bodyParser.json()) //解析 cookie app.use(cookieParser()) //拦截 app.get('/hello', function (req, res) { res.send('Hello World!'); });
ミドルウェアメカニズムをシミュレートし、解析リクエストを実装するミドルウェアをシミュレートします
最初にリクエスト
をシミュレートしますrequest
request = { //模拟的request requestLine: 'POST /iven_ HTTP/1.1', headers: 'Host:www.php.cn\r\nCookie:BAIDUID=E063E9B2690116090FE24E01ACDDF4AD:FG=1;BD_HOME=0', requestBody: 'key1=value1&key2=value2&key3=value3', }
一个http
请求分为请求行、请求头、和请求体,这三者之间通过rnrn
即一个空行来分割,这里假设已经将这三者分开,requestLine
(请求行)中有方法类型,请求url,http版本号,这三者通过空格来区分,headers
(请求头)中的各部分通过rn
来分割,requestBody
function App() {
if (!(this instanceof App))
return new App();
this.init();
}
App.prototype = {
constructor: App,
init: function() {
this.request = { //模拟的request
requestLine: 'POST /iven_ HTTP/1.1',
headers: 'Host:www.php.cn\r\nCookie:BAIDUID=E063E9B2690116090FE24E01ACDDF4AD:FG=1;BD_HOME=0',
requestBody: 'key1=value1&key2=value2&key3=value3',
};
this.response = {}; //模拟的response
this.chain = []; //存放中间件的一个数组
this.index = 0; //当前执行的中间件在chain中的位置
},
use: function(handle) { //这里默认 handle 是函数,并且这里不做判断
this.chain.push(handle);
},
next: function() { //当调用next时执行index所指向的中间件
if (this.index >= this.chain.length)
return;
let middleware = this.chain[this.index];
this.index++;
middleware(this.request, this.response, this.next.bind(this));
},
}
http
リクエストは、リクエストライン、リクエストヘッダ、リクエストボディに分かれており、これら 3 つは rnrn
、つまり空行で区切られているものとします。 requestLine
(リクエスト行) にはメソッドタイプ、リクエスト URL、http バージョン番号が含まれており、これら 3 つは headers
(リクエストヘッダー) で区切られています。 ) rn
で分割され、パラメータは requestBody
(リクエストボディ) の & で区別されます
function lineParser(req, res, next) { let items = req.requestLine.split(' '); req.methond = items[0]; req.url = items[1]; req.version = items[2]; next(); //执行下一个中间件 } function headersParser(req, res, next) { let items = req.headers.split('\r\n'); let header = {} for(let i in items) { let item = items[i].split(':'); let key = item[0]; let value = item[1]; header[key] = value; } req.header = header; next(); //执行下一个中间件 } function bodyParser(req, res, next) { let bodyStr = req.requestBody; let body = {}; let items = bodyStr.split('&'); for(let i in items) { let item = items[i].split('='); let key = item[0]; let value = item[1]; body[key] = value; } req.body = body; next(); //执行下一个中间件 } function middleware3(req, res, next) { console.log('url: '+req.url); console.log('methond: '+req.methond); console.log('version: '+req.version); console.log(req.body); console.log(req.header); next(); //执行下一个中间件 }
リクエスト処理用のミドルウェア
let app = App(); app.use(lineParser); app.use(headersParser); app.use(bodyParser); app.use(middleware3); app.next();
function App() { if (!(this instanceof App)) return new App(); this.init(); } App.prototype = { constructor: App, init: function() { this.request = { //模拟的request requestLine: 'POST /iven_ HTTP/1.1', headers: 'Host:www.php.cn\r\nCookie:BAIDUID=E063E9B2690116090FE24E01ACDDF4AD:FG=1;BD_HOME=0', requestBody: 'key1=value1&key2=value2&key3=value3', }; this.response = {}; //模拟的response this.chain = []; //存放中间件的一个数组 this.index = 0; //当前执行的中间件在chain中的位置 }, use: function(handle) { //这里默认 handle 是函数,并且这里不做判断 this.chain.push(handle); }, next: function() { //当调用next时执行index所指向的中间件 if (this.index >= this.chain.length) return; let middleware = this.chain[this.index]; this.index++; middleware(this.request, this.response, this.next.bind(this)); }, } function lineParser(req, res, next) { let items = req.requestLine.split(' '); req.methond = items[0]; req.url = items[1]; req.version = items[2]; next(); //执行下一个中间件 } function headersParser(req, res, next) { let items = req.headers.split('\r\n'); let header = {} for(let i in items) { let item = items[i].split(':'); let key = item[0]; let value = item[1]; header[key] = value; } req.header = header; next(); //执行下一个中间件 } function bodyParser(req, res, next) { let bodyStr = req.requestBody; let body = {}; let items = bodyStr.split('&'); for(let i in items) { let item = items[i].split('='); let key = item[0]; let value = item[1]; body[key] = value; } req.body = body; next(); //执行下一个中间件 } function middleware3(req, res, next) { console.log('url: '+req.url); console.log('methond: '+req.methond); console.log('version: '+req.version); console.log(req.body); console.log(req.header); next(); //执行下一个中间件 } let app = App(); app.use(lineParser); app.use(headersParser); app.use(bodyParser); app.use(middleware3); app.next();
全体のコード
りー
走る結果
url: /iven_ methond: POST version: HTTP/1.1 {key1: "value1", key2: "value2", key3: "value3"} {Host: "www.php.cn", Cookie: "BAIDUID=E063E9B2690116090FE24E01ACDDF4AD"}
以上がExpressミドルウェアの仕組みとその実装原理を分析するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。