ホームページ ウェブフロントエンド jsチュートリアル Node.js 開発 - エクスプレス ルーティングとミドルウェアの詳細なコード例

Node.js 開発 - エクスプレス ルーティングとミドルウェアの詳細なコード例

Mar 25, 2017 pm 02:35 PM

この記事では、主にnodejs開発 - エクスプレスルーティングとミドルウェアについて紹介します。編集者が非常に優れていると考えたので、参考として共有します。エディターをフォローして一緒に見てみましょう

ルーティング

通常、HTTP URL の形式は次のとおりです:

host[:port][path]
ログイン後にコピー

http はプロトコルを表します。

hostとはホストという意味です。

port はポートであり、オプションのフィールドであり、指定しない場合のデフォルトは 80 です。

path は、リクエストされたリソースの URI (Uniform Resource Identifier、Uniform Resource Locator) を指定します。URL でパスが指定されていない場合、通常はデフォルトで「/」になります (通常はブラウザーまたは他の HTTP クライアントによって補完されます)。

いわゆるルーティングとは、HTTPリクエストのパス部分をどのように処理するかです。たとえば、URL「xxx.com/users/profile」の場合、ルーティングによってパス /users/profile を処理する方法が決まります。

「Node.js 開発入門 - 高速インストールと使用」で提供した HelloWorld コードの高速バージョンを確認してみましょう:

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

app.get('/', function (req, res) {
 res.send('Hello World!');
});

app.listen(8000, function () {
 console.log('Hello World is listening at port 8000');
});
ログイン後にコピー

上記のコードの app.get() 呼び出しは、実際に Web サイトのルーティングにエントリを追加します。パス「/」は get の 2 番目のパラメーターで表される 関数 によって処理されることを示します。

express オブジェクト は、次のメソッドを使用して一般的な HTTP メソッドのルートを指定できます:

app.METHOD(path, callback [, callback ...])
ログイン後にコピー

ルーティング パス

string を使用したルーティング パスの例:

// 匹配根路径的请求

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

 res.send('root');

});

// 匹配 /about 路径的请求

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

 res.send('about');

});

// 匹配 /random.text 路径的请求

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

 res.send('random.text');

});

使用字符串模式的路由路径示例:

// 匹配 acd 和 abcd

app.get('/ab?cd', function(req, res) {

 res.send('ab?cd');

});

// 匹配 abcd、abbcd、abbbcd等

app.get('/ab+cd', function(req, res) {

 res.send('ab+cd');

});

// 匹配 abcd、abxcd、abRABDOMcd、ab123cd等

app.get('/ab*cd', function(req, res) {

 res.send('ab*cd');

});

// 匹配 /abe 和 /abcde

app.get('/ab(cd)?e', function(req, res) {

 res.send('ab(cd)?e');

});
ログイン後にコピー

文字 ?、+、* および() は 正規表現 のサブセットであり、- と . は文字列ベースのパスで文字通り解釈されます。

正規表現を使用したルーティングパスの例:

// 匹配任何路径中含有 a 的路径:

app.get(/a/, function(req, res) {

 res.send('/a/');

});

// 匹配 butterfly、dragonfly,不匹配 butterflyman、dragonfly man等

app.get(/.*fly$/, function(req, res) {

 res.send('/.*fly$/');

});
ログイン後にコピー

ルートハンドル

は、リクエスト処理のためにミドルウェアのように動作する複数のコールバック関数を提供できます。唯一の違いは、これらのコールバック関数が next('route') メソッドを呼び出し、他のルート コールバック関数をスキップできることです。このメカニズムはルーティングの前提条件を定義するために使用でき、既存のパスで実行を継続することが意味がない場合は、残りのパスに制御を与えることができます。

ルート ハンドルにはさまざまな形式があり、以下に示すように、関数、関数の配列、またはその 2 つの組み合わせにすることができます。

1 つのコールバック関数を使用してルーティングを処理します。

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

 res.send('Hello from A!');

});
ログイン後にコピー

複数のコールバック関数を使用して処理します。ルーティング (次のオブジェクトを指定することを忘れないでください):

app.get('/example/b', function (req, res, next) {

 console.log('response will be sent by the next function ...');

 next();

}, function (req, res) {

 res.send('Hello from B!');

});
ログイン後にコピー

コールバック関数配列を使用してルーティングを処理します:

var cb0 = function (req, res, next) {

 console.log('CB0');

 next();

}

var cb1 = function (req, res, next) {

 console.log('CB1');

 next();

}

var cb2 = function (req, res) {

 res.send('Hello from C!');

}

app.get('/example/c', [cb0, cb1, cb2]);
ログイン後にコピー

混合関数 と関数配列を使用してルーティングを処理します:

var cb0 = function (req, res, next) {

 console.log('CB0');

 next();

}

var cb1 = function (req, res, next) {

 console.log('CB1');

 next();

}

app.get('/example/d', [cb0, cb1], function (req, res, next) {

 console.log('response will be sent by the next function ...');

 next();

}, function (req, res) {

 res.send('Hello from D!');
ログイン後にコピー

METHOD は GET などの HTTP メソッドの小文字にすることができます、POST など、app.get、app post。パス部分には文字列リテラルまたは正規表現を使用できます。最も単純な例は、前のコードの app.get() 呼び出しのパラメーター '/' を '*' に変更することです。これにより、意味が異なります。変更前は、「localhost:8000」または「localhost:8000/」の形式でアクセスした場合のみ「Hello World!」が返されましたが、変更後は「localhost:8000/xxx/yyyy.zz」の場合に Access が返されるようになります。 「Hello World!」も返します。

Express を使用して Web サーバーを構築する場合、特定のパスに対するリクエストにどのように応答するか、つまりルーティング処理を決定することが作業の非常に重要な部分です。

最も直接的なルート設定方法は、app.get() と app.post() を呼び出して 1 つずつ設定することです。ただし、多数のルートを処理する必要がある Web サイトの場合、これは危険です。したがって、実際の開発では、ルーティングパラメータ (クエリ文字列、正規表現、カスタムパラメータ、ポストパラメータ) を組み合わせて作業負荷を軽減し、保守性を向上させる必要があります。

ミドルウェア

Expressにはミドルウェアという概念があります。いわゆるミドルウェアとは、リクエストを受信した後、レスポンスを送信するまでのこの段階で実行されるいくつかの機能を指します。

ルートの処理チェーンにミドルウェアを挿入するには、Express オブジェクトの use メソッドを使用できます。このメソッドのプロトタイプは次のとおりです。

app.use([path,] function [, function...])
ログイン後にコピー

app.use がパス パラメーターを提供しない場合、パスはデフォルトの「/」になります。パスにミドルウェアをインストールすると、そのパスに基づくパスにアクセスするたびにミドルウェアが適用されます。たとえば、「/abcd」にミドルウェアを設定すると、「/abcd/xxx」にアクセスしたときにもミドルウェアが適用されます。

ミドルウェア関数のプロトタイプは次のとおりです:

function (req, res, next)
ログイン後にコピー

最初のパラメータはRequestオブジェクトreqです。 2 番目のパラメーターは、R​​esponse オブジェクトの res です。 3 番目の関数は、ミドルウェア呼び出しチェーンを駆動するために次に使用される関数です。後続のミドルウェアでリクエストの処理を続行するには、次のメソッドを呼び出す必要があります。

特定のパスにミドルウェア関数を適用する一般的な呼び出しは次のとおりです:

app.use('/abcd', function (req, res, next) {
 console.log(req.baseUrl);
 next();
})
ログイン後にコピー

app.static middleware

Express は、Web サイト上の static ファイルの GET を処理するために使用できる静的ミドルウェアを提供します。 Express.static を通じてアクセスできます。

express.staticの使用法は次のとおりです:

express.static(root, [options])
ログイン後にコピー

第一个参数root,是要处理的静态资源的根目录,可以是绝对路径,也可以是相对路径。第二个可选参数用来指定一些选项,比如maxAge、lastModified等,

一个典型的express.static应用如下:

var options = {
 dotfiles: 'ignore',
 etag: false,
 extensions: ['htm', 'html'],
 index: false,
 maxAge: '1d',
 redirect: false,
 setHeaders: function (res, path, stat) {
  res.set('x-timestamp', Date.now());
 }
}

app.use(express.static('public', options));
ログイン後にコピー

上面这段代码将当前路径下的public目录作为静态文件,并且为Cache-Control头部的max-age选项为1天。还有其它一些属性,请对照express.static的文档来理解。

使用express创建的HelloExpress项目的app.js文件里有这样一行代码:

app.use(express.static(path.join(dirname, 'public')));
ログイン後にコピー

这行代码将HelloExpress目录下的public目录作为静态文件交给static中间件来处理,对应的HTTP URI为“/”。path是一个Node.js模块,dirname是Node.js的全局变量,指向当前运行的js脚本所在的目录。path.join()则用来拼接目录。

有了上面的代码,你就可以在浏览器里访问“localhost:3000/stylesheets/style.css”。我们做一点改动,把上面的代码修改成下面这样:

app.use('/static', express.static(path.join(dirname, 'public')));
ログイン後にコピー

上面的代码呢,针对/static路径使用static中间件处理public目录。这时你再用浏览器访问“localhost:3000/stylesheets/”就会看到一个404页面,将地址换成“localhost:3000/static/stylesheets/style.css”就可以了。

Router

Express还提供了一个叫做Router的对象,行为很像中间件,你可以把Router直接传递给app.use,像使用中间件那样使用Router。另外你还可以使用router来处理针对GET、POST等的路由,也可以用它来添加中间件,总之你可以将Router看作一个微缩版的app。

下面的代码创建一个Router实例:

var router = express.Router([options]);
ログイン後にコピー

然后你就可以像使用app一样使用router:

// invoked for any requests passed to this router
router.use(function(req, res, next) {
 // .. some logic here .. like any other middleware
 next();
});

// will handle any request that ends in /events
// depends on where the router is "use()'d"
router.get('/events', function(req, res, next) {
 // ..
});
ログイン後にコピー

定义了router后,也可以将其作为中间件传递给app.use:

app.use('/events', router);
ログイン後にコピー

上面这种用法,会针对URL中的“/events”路径应用router,你在router对象上配置的各种路由策略和中间件,都会被在合适的时候应用。

路由模块

express工具创建的应用,有一个routes目录,下面保存了应用到网站的Router模块,index.js和user.js。这两个模块基本一样,我们研究一下index.js。

下面是index.js的内容:

var express = require('express');
var router = express.Router();

/* GET home page. */
router.get('/', function(req, res, next) {
 res.render('index', { title: 'Express' });
});

module.exports = router;
ログイン後にコピー

index.js创建了一个Router实例,然后调用router.get为“/”路径应用了路由函数。最后呢使用module.exports将Router对象导出。

下面是app.js里引用到index.js的代码:

var routes = require('./routes/index');
...
app.use('/', routes);
ログイン後にコピー

第一处,require(‘./routes/index')将其作为模块使用,这行代码导入了index.js,并且将index.js导出的router对象保存在变量routes里以供后续使用。注意,上面代码里的routes就是index.js里的router。

第二处代码,把routes作为一个中间件,挂载到了“/”路径上。

模块

前面分析index.js时看到了module.exports的用法。module.exports用来导出一个Node.js模块内的对象,调用者使用require加载模块时,就会获得导出的对象的实例。

我们的index.js导出了Router对象。app.js使用require(‘./routes/index')获取了一个Router实例。

module.exports还有一个辅助用法,即直接使用exports来导出。

exports.signup = function(req, res){
 //some code
}

exports.login = function(req, res){
 //some code
}
ログイン後にコピー

上面的代码(假定在users.js文件里)直接使用exports来导出。当使用exports来导出时,你设置给exports的属性和方法,实际上都是module.exports的。这个模块最终导出的是module.exports对象,你使用类似“exports.signup”这种形式设置的方法或属性,调用方在require后都可以直接使用。

使用users模块的代码可能是这样的:

var express = require('express');
var app = express();
...
var users = require('./routes/users');
app.post('/signup', users.signup);
app.post('/login', users.login);
...
ログイン後にコピー

1. 什么是router路径,什么是middleware?

我们输入www.baidu.com 来访问百度的主页,浏览器会自动转换为 www.baidu.com:80/(省略一些参数)。 http://代表我们同服务器连接使用的是http协议,www.baidu.com 代表的是服务器的主机地址,会被我们的pc通过DNS解析为IP地址。80是默认的应用层端口。/ 即为我们访问的服务器(www.baidu.com)的路径,服务器要对我们访问的这个路径做出响应,采取一定的动作。我们可以把这一过程看做一个路由。

访问的路径‘/'即为router的路径,服务器采取的动作即为middleware,即为一个个特殊的函数。

2. router路径

www.baidu.com/test: 路径为 /test

www.baidu.com/test?name=1&number=2: 路径同样为/test, ?后面会被服务器理解传给路径的参数。

3. Middleware

An Express application is essentially a stack of middleware which are executed serially.(express应用其实就是由一系列顺序执行的Middleware组成。)

A middleware is a function with access to the request object (req), the response object (res), and the next middleware in line in the request-response cycle of an Express application. It is commonly denoted by a variable named next. Each middleware has the capacity to execute any code, make changes to the request and the reponse object, end the request-response cycle, and call the next middleware in the stack. Since middleware are execute serially, their order of inclusion is important.(中间件其实就是一个访问express应用串入的req,res,nex参数的函数,这个函数可以访问任何通过req,res传入的资源。)

If the current middleware is not ending the request-response cycle, it is important to call next() to pass on the control to the next middleware, else the request will be left hanging.(如果当前中间件没有完成对网页的res响应 ,还可以通过next把router 留给下一个middleware继续执行)

With an optional mount path, middleware can be loaded at the application level or at the router level. Also, a series of middleware functions can be loaded together, creating a sub-stack of middleware system at a mount point.

路由的产生是通过HTTP的各种方法(GET, POST)产生的,Middleware可以跟router路径跟特定的HTTP方法绑定,也可以跟所有的方法绑定。

3.1 通过express应用的use(all),把Middleware同router路径上的所有HTTP方法绑定:

 app.use(function (req, res, next) {
  console.log('Time: %d', Date.now());
  next();
 })
ログイン後にコピー

3.2 通过express应用的http.verb,把Middleware同router路径上的特定的HTTP方法绑定:

app.get('/', function(req, res){
 res.send('hello world');
});


app.post('/', function(req, res){
 res.send('hello world');
});
ログイン後にコピー

4. Express的Router对象

当express实例的路由越来越多的时候,最好把路由分类独立出去,express的实例(app) 能更好的处理其他逻辑流程。Express的Router对象是一个简化的 app实例,只具有路由相关的功能,包括use, http verbs等等。最后这个Router再通过app的use挂载到app的相关路径下。

 var express = require('express');
var app = express();
var router = express.Router();

// simple logger for this router's requests
// all requests to this router will first hit this middleware
router.use(function(req, res, next) {
 console.log('%s %s %s', req.method, req.url, req.path);
 next();
});

// this will only be invoked if the path ends in /bar
router.use('/bar', function(req, res, next) {
 // ... maybe some additional /bar logging ...
 next();
});

// always invoked
router.use(function(req, res, next) {
 res.send('Hello World');
});

app.use('/foo', router);

app.listen(3000);
ログイン後にコピー

router的路由必须通过app.use和app.verbs 挂载到app上才能被响应。所以上述代码,只有在app捕捉到 /foo路径上的路由时,才能router中定义的路由,虽然router中有针对 '/' 的路由,但是被app中的路由给覆盖了。

附:app.verbs和app.use的路由路径区别:

先看一段测试代码:

var express = require('express');

var app = express();
var router = express.Router();

app.get('/', function(req, res){
   console.log('test1');
});

app.use('/', function(req, res){
   console.log('test2');
});

router.get('/', function(req, res){
   console.log('test3');
});

app.listen(4000);
ログイン後にコピー

输入url: localhost:4000

输出结果:test1 

输入url: localhost:4000/hello

输出结果:test2

结论:app.get挂载‘/'的路由只响应跟'/'精确匹配的GET请求。 而app.use挂载的'/'的路由响应所有以'/' 为起始路由的路由,且不限制HTTP访问的方法。以下说明:Mounting a middleware at a path will cause the middleware function to be executed whenever the base of the requested path matches the path.

以上がNode.js 開発 - エクスプレス ルーティングとミドルウェアの詳細なコード例の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Tomcatミドルウェアの原理は何ですか Tomcatミドルウェアの原理は何ですか Dec 27, 2023 pm 04:40 PM

Tomcat ミドルウェアの原理は、Java Servlet および Java EE 仕様に基づいて実装されています。 Tomcat はサーブレット コンテナとして、HTTP リクエストとレスポンスを処理し、Web アプリケーションに実行環境を提供する役割を果たします。 Tomcat ミドルウェアの原理には主に次のものが含まれます: 1. コンテナ モデル; 2. コンポーネント アーキテクチャ; 3. サーブレット処理メカニズム; 4. イベント リスニングとフィルター; 5. 構成管理; 6. セキュリティ; 7. クラスタリングとロード バランシング; 8. コネクタテクノロジー; 9. エンベデッドモードなど

Laravelでのレスポンス変換にミドルウェアを使用する方法 Laravelでのレスポンス変換にミドルウェアを使用する方法 Nov 03, 2023 am 09:57 AM

Laravel での応答変換にミドルウェアを使用する方法 ミドルウェアは、Laravel フレームワークの非常に強力で実用的な機能の 1 つです。これにより、リクエストがコントローラーに入る前、またはレスポンスがクライアントに送信される前に、リクエストとレスポンスを処理できるようになります。この記事では、Laravel でレスポンス変換にミドルウェアを使用する方法を説明します。始める前に、Laravel がインストールされており、新しいプロジェクトが作成されていることを確認してください。次に、次の手順に従います。 新しいミドルウェアを作成する 開く

Laravelでデータ高速化のためのミドルウェアを使用する方法 Laravelでデータ高速化のためのミドルウェアを使用する方法 Nov 02, 2023 am 09:40 AM

Laravel でデータ アクセラレーションのためのミドルウェアを使用する方法 はじめに: Laravel フレームワークを使用して Web アプリケーションを開発する場合、データ アクセラレーションがアプリケーションのパフォーマンスを向上させる鍵となります。ミドルウェアは、Laravel が提供する重要な機能で、リクエストがコントローラーに到達する前、または応答が返される前に処理します。この記事では、ミドルウェアを使用して Laravel でデータ高速化を実現する方法に焦点を当て、具体的なコード例を示します。 1. ミドルウェアとは何ですか? ミドルウェアはLaravelフレームワークの仕組みです。

Laravelでミドルウェアを使用してフォーム検証を処理する方法 Laravelでミドルウェアを使用してフォーム検証を処理する方法 Nov 02, 2023 pm 03:57 PM

ミドルウェアを使用して Laravel でフォーム検証を処理する方法、特定のコード例が必要です はじめに: フォーム検証は Laravel で非常に一般的なタスクです。ユーザーが入力したデータの有効性と安全性を確保するために、当社は通常、フォームに送信されたデータを検証します。 Laravel は便利なフォーム検証機能を提供しており、フォーム検証を処理するためのミドルウェアの使用もサポートしています。この記事では、ミドルウェアを使用してLaravelでフォーム検証を処理する方法を詳しく紹介し、具体的なコード例を示します。

Laravelでスケジュールされたタスクのスケジューリングにミドルウェアを使用する方法 Laravelでスケジュールされたタスクのスケジューリングにミドルウェアを使用する方法 Nov 02, 2023 pm 02:26 PM

Laravel でスケジュールされたタスクのスケジューリングにミドルウェアを使用する方法 はじめに: Laravel は、Web アプリケーションを開発するための便利で強力なツールを提供する、人気のある PHP オープン ソース フレームワークです。重要な機能の 1 つはスケジュールされたタスクです。これにより、開発者は指定された間隔で特定のタスクを実行できます。この記事では、ミドルウェアを使用してLaravelのスケジュールされたタスクのスケジューリングを実装する方法と、具体的なコード例を紹介します。環境の準備 始める前に確認する必要があります

Express と Laravel の詳細な比較: 最適なフレームワークを選択するには? Express と Laravel の詳細な比較: 最適なフレームワークを選択するには? Mar 09, 2024 pm 01:33 PM

Express と Laravel の詳細な比較: 最適なフレームワークを選択するには?プロジェクトに適したバックエンド フレームワークを選択する場合、Express と Laravel が開発者の間で人気のある 2 つの選択肢であることは間違いありません。 Express は Node.js ベースの軽量フレームワークであり、Laravel は PHP ベースの人気のあるフレームワークです。この記事では、これら 2 つのフレームワークの長所と短所を詳しく比較し、開発者がニーズに最適なフレームワークを選択できるように、具体的なコード例を示します。パフォーマンスとスケーラビリティExpr

Slim フレームワークのミドルウェアを使用してクロスドメイン リソース共有 (CORS) を設定する方法 Slim フレームワークのミドルウェアを使用してクロスドメイン リソース共有 (CORS) を設定する方法 Jul 30, 2023 pm 08:34 PM

Slim フレームワークでミドルウェアを使用してクロス オリジン リソース シェアリング (CORS) を設定する方法 クロス オリジン リソース シェアリング (CORS) は、サーバーが HTTP 応答ヘッダーに追加情報を設定して、ブラウザーに相互接続を許可するかどうかを伝えることができるメカニズムです。 -オリジンリクエスト。フロントエンドとバックエンドが分離されている一部のプロジェクトでは、CORS メカニズムを使用して、バックエンド インターフェイスに対するフロントエンドのクロスドメイン要求を実現できます。 Slim フレームワークを使用して REST API を開発する場合、ミドルウェア (Middleware) を使用できます。

PHPのリアルタイム通信機能とメッセージプッシュミドルウェアの関係の分析 PHPのリアルタイム通信機能とメッセージプッシュミドルウェアの関係の分析 Aug 10, 2023 pm 12:42 PM

PHPのリアルタイム通信機能とメッセージプッシュミドルウェアの関係の分析 インターネットの発展に伴い、Webアプリケーションにおけるリアルタイム通信機能の重要性がますます高まっています。リアルタイム通信により、ユーザーはアプリケーション内でリアルタイムにメッセージを送受信できるようになり、リアルタイム チャット、即時通知などのさまざまなシナリオに適用できます。 PHP の分野では、リアルタイム通信機能を実装する方法は数多くありますが、一般的な方法の 1 つはメッセージ プッシュ ミドルウェアを使用することです。この記事では、PHPのリアルタイム通信機能とメッセージプッシュミドルウェアの関係と、メッセージプッシュの利用方法について紹介します。

See all articles