> 웹 프론트엔드 > JS 튜토리얼 > Express 미들웨어 메커니즘 및 구현 원리 분석

Express 미들웨어 메커니즘 및 구현 원리 분석

巴扎黑
풀어 주다: 2017-09-01 10:18:42
원래의
998명이 탐색했습니다.

이 기사는 주로 Express 미들웨어 메커니즘과 구현 원리를 소개합니다. 편집자는 이것이 꽤 좋다고 생각합니다. 이제 이를 여러분과 공유하고 참고하겠습니다. 편집기를 따라 살펴보겠습니다

소개

미들웨어 메커니즘을 사용하면 주어진 프로세스에 처리 단계를 추가하여 프로세스의 입력 또는 출력에 영향을 주거나 일부 중간 효과, 상태 또는 이 과정을 가로채세요. 미들웨어 메커니즘은 Tomcat의 필터와 유사하며 둘 다 책임 체인 모델의 특정 구현입니다. middlegresspress 미들웨어 사용 사례


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!');
});
로그인 후 복사


r

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',
}
로그인 후 복사

r

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));
  },
}
로그인 후 복사
simulate middleware 메커니즘을 시뮬레이션하고 구문 분석 요청을 구현하는 미들웨어를 시뮬레이션합니다. http 요청은 요청 라인, 요청 헤더, 요청 본문으로 나누어지며, 이 세 가지는 rnrn, 즉 빈 라인으로 구분됩니다. 별도로 분리되어 있으며, requestLine(요청 라인)에는 메소드 유형, 요청 URL 및 http 버전 번호가 포함됩니다. 이 세 가지는 헤더(요청 헤더)의 각 부분으로 구분됩니다. ) rn으로 분할되고 매개변수는 requestBody(요청 본문)에서 &로 구분됩니다.

미들웨어 메커니즘 시뮬레이션request


 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(); //执行下一个中间件
}
로그인 후 복사

一个http请求分为请求行、请求头、和请求体,这三者之间通过rnrn即一个空行来分割,这里假设已经将这三者分开,requestLine(请求行)中有方法类型,请求url,http版本号,这三者通过空格来区分,headers(请求头)中的各部分通过rn来分割,requestBody

미들웨어는 다음과 같아야 한다는 데 동의합니다. 함수 및 요청 수락, 응답, 다음 세 가지 매개변수

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"}
로그인 후 복사

전체 코드


rrreee

달려 결과

위 전체 코드를 실행하면 다음과 같은 정보가 출력됩니다

rrreee

위 내용은 Express 미들웨어 메커니즘 및 구현 원리 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿