// app.js var express = require("express"); var app = express(); app.get("/", function (req, res) { res.send("Hello World!"); }); app.listen(3000, function () { console.log("Example app listening on port 3000!"); });
应用生成器工具
通过应用生成器工具 express-generator 可以快速创建一个应用的骨架。
1 2 3 4
npm install express-generator-g express helloworld cd helloworld npm install
1 2 3 4
# Run the helloworld on Windows SET DEBUG=helloworld:* & npm start # Run helloworld on Linux/Mac OS X DEBUG=helloworld:* npm start
helloworld:server Listening on port 3000 +0ms GET / 200 296.211 ms - 170 GET /stylesheets/style.css 200 4.926 ms - 111 GET /favicon.ico 404 18.522 ms - 1292
控制器:从模型中获取请求的数据,创建一个 HTML 页面显示出数据,并将页面返回给用户,以便在浏览器中查看。
视图(模板):供控制器用来渲染数据。
基本路由
路由用于确定应用程序如何响应对特定端点的客户机请求,包含一个 URI(或路径)和一个特定的 HTTP 请求方法(GET、 POST 等)。
每个路由可以具有一个或多个处理程序函数,这些函数在路由匹配时执行。
路由定义采用以下结构:
app.METHOD(PATH, HANDLER) 其中:
app 是 express 的实例。
METHOD 是 HTTP 请求方法。
PATH 是服务器上的路径。
HANDLER 是在路由匹配时执行的函数。
路由示例
以主页上的 Hello World!进行响应:
1 2 3
app.get("/", function (req, res) { res.send("Hello World!"); });
在根路由(/)上(应用程序的主页)对 POST 请求进行响应:
1 2 3
app.post("/", function (req, res) { res.send("Got a POST request"); });
对/user 路由的 PUT 请求进行响应:
1 2 3
app.put("/user", function (req, res) { res.send("Got a PUT request at /user"); });
app.js or routes/index.js
1 2 3 4 5 6
var express = require("express"); var app = express(); // respond with "hello world" when a GET request is made to the homepage app.get("/", function (req, res) { res.send("hello world"); });
路由方法
路由方法派生自 HTTP 方法之一,附加到 express 类的实例。
1 2 3 4 5 6 7 8
// GET method route app.get("/", function (req, res) { res.send("GET request to the homepage"); }); // POST method route app.post("/", function (req, res) { res.send("POST request to the homepage"); });
// 单个回调函数可以处理一个路由。例如: app.get("/example/a", function (req, res) { res.send("Hello from A!"); }); // 多个回调函数可以处理一个路由(确保您指定 next 对象)。例如: app.get( "/example/b", function (req, res, next) { console.log("the response will be sent by the next function ..."); next(); }, function (req, res) { res.send("Hello from B!"); } );
1 2 3 4 5 6 7 8 9 10 11 12 13
// 一组回调函数可以处理一个路由。例如: 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("the response will be sent by the next function ..."); next(); }, function (req, res) { res.send("Hello from D!"); } );
var express = require("express"); var router = express.Router(); // middleware that is specific to this router router.use(functiontimeLog(req, res, next) { console.log("Time: ", Date.now()); next(); }); // define the home page route router.get("/", function (req, res) { res.send("Birds home page"); }); // define the about route router.get("/about", function (req, res) { res.send("About birds"); }); module.exports = router;
接着,在应用程序中装入路由器模块:
1 2 3
var birds = require('./birds'); ... app.use('/birds', birds);
路由处理程序可以为一个路径定义多个路由。以下示例为针对 /user/:id 路径的 GET 请求定义两个路由。第二个路由不会导致任何问题,但是永远都不会被调用,因为第一个路由结束了请求/响应循环。 此示例显示一个中间件子堆栈,用于处理针对 /user/:id 路径的 GET 请求。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
app.get( "/user/:id", function (req, res, next) { console.log("ID:", req.params.id); next(); }, function (req, res, next) { res.send("User Info"); } ); // handler for the /user/:id path, which prints the user ID app.get("/user/:id", function (req, res, next) { res.end(req.params.id); });
app.get( "/user/:id", function (req, res, next) { // if the user ID is 0, skip to the next route if (req.params.id == 0) next("route"); // otherwise pass the control to the next middleware function in this stack elsenext(); // }, function (req, res, next) { // render a regular page res.render("regular"); } ); // handler for the /user/:id path, which renders a special page app.get("/user/:id", function (req, res, next) { res.render("special"); });
var app = express(); var router = express.Router(); // a middleware function with no mount path. This code is executed for every request to the router router.use(function (req, res, next) { console.log("Time:", Date.now()); next(); }); // a middleware sub-stack shows request info for any type of HTTP request to the /user/:id path router.use( "/user/:id", function (req, res, next) { console.log("Request URL:", req.originalUrl); next(); }, function (req, res, next) { console.log("Request Type:", req.method); next(); } ); // a middleware sub-stack that handles GET requests to the /user/:id path router.get( "/user/:id", function (req, res, next) { // if the user ID is 0, skip to the next router if (req.params.id == 0) next("route"); // otherwise pass control to the next middleware function in this stack elsenext(); // }, function (req, res, next) { // render a regular page res.render("regular"); } ); // handler for the /user/:id path, which renders a special page router.get("/user/:id", function (req, res, next) { console.log(req.params.id); res.render("special"); }); // mount the router on the app app.use("/", router);
错误处理中间件
错误处理中间件始终采用四个自变量。必须提供四个自变量,以将函数标识为错误处理中间件函数。即使无需使用 next 对象,也必须指定该对象以保持特征符的有效性。否则,next 对象将被解释为常规中间件,从而无法处理错误。
var express = require("express"); var app = express(); var cookieParser = require("cookie-parser"); // load the cookie-parsing middleware app.use(cookieParser());