Express Learning Notes Pure Dry Goods (Routing, Middleware, Hosted Static Files, Viewengine, etc.)

Links to original articles: http://www.lovebxm.com/2017/0...

1. Express Profile

Express is a fast, open and minimal web development framework based on Node.js platform. It provides a series of powerful features to help you create various Web and mobile applications.

Express does not re-abstract the existing features of Node.js, but only extends the basic functions required by Web applications.

<!-- more -->

Express is a simple web development framework composed of routing and middleware: essentially, an Express application is calling various middleware.

API aspect: Rich HTTP shortcuts and arbitrary combination of Connect middleware make it fast and easy to create robust and friendly APIs.

Characteristic:

  • Robust routing

  • Focus on high performance

  • Super-high test coverage

  • HTTP helpers (redirection, caching, etc)

  • View system supporting 14+ template engines

  • Content negotiation

  • Executable for generating applications quickly

Installation and hello world

--save: When you install a module, if you specify the -- save parameter, the module will be added to the dependencies dependencies list in the package.json file. The npm install command then automatically installs all the modules listed in the dependency list. If it's just a temporary installation and you don't want to add it to the dependency list, just omit the -- save parameter.

Cranking: When I installed it, I created a project folder called express. After initialization, I installed express. There was an error (Refusing to install express as a dependency of itself). The reason is that the name of the project folder and the project to be installed depend on the rename. In fact, the name in package.json file is also express at this time. This will make a mistake and can't have the same name, so we need to delete everything again.

# Working Directory
$ mkdir myapp
$ cd myapp

# Create a package.json file for your application through the npm init command
$ npm init

Entry file for # application
entry point: app.js

# Install Express and save it in the dependency list
$ npm install express --save

The following code starts a service and listens for all connection requests coming from port 3000. He will return the hello world string to all (/) URL s or routes. Return 404 Not Found for all other paths.

req (request, request) and res (response, response) are identical to the objects provided by Node, so you can call req.pipe(), req.on('data', callback) and any methods provided by Node.

const express = require('express');

let app = express();

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

let server = app.listen(3000, function () {
    let host = server.address().address;
    let port = server.address().port;

    console.log(`app listening at port: ${port}`);
});
# Start this application
$ node app.js

http://localhost:3000/

Express Application Generator

With the application generator tool, express can quickly create an application skeleton.

Creating an application through Express Application Generator is just one of many ways you can modify it to suit your needs.

# install
$ npm install express-generator -g

# List all available commands
$ express -h

# Initialize an express project
$ express myapp
$ cd myapp

# Then install all dependency packages
$ npm install

# Start this application
$ npm start

http://localhost:3000/

2. Routing

http://www.expressjs.com.cn/g...

Routing refers to how to define application endpoints (URIs) and how to respond to client requests.

Routing is composed of a URI (path) and a specific HTTP method (get, post, put, delete, etc.). It involves how the application responds to the client's access to a site node.

structure

The definition of routing consists of the following structure:

  • app is an express instance

  • method is a HTTP request mode Express defines the following routing methods corresponding to HTTP requests: get, post, put, head, delete, options, trace, copy, lock, mkcol, move, purge, propfind, proppatch, unlock, report, mkactivity, checkout, merge, m-search, notify, subscribe, bscribe, patch, search, connect. Some routing method names are not compliant JavaScript variable names, using parentheses, such as app['m-search']('/', function...

  • path Is the server-side path

  • handler Each routing can have one or more processor functions that will be executed when matched to the routing.

app.method(path, [handler...], handler)
// respond with "hello world" when a GET request is made to the homepage
app.get('/', function (req, res) {
  res.send('Hello World!');
});

app.all() is a special routing method, and no HTTP method corresponds to it. Its function is to load middleware for all requests on a path.

In the following example, requests from / secret, whether using GET, POST or any other HTTP request, are executed.

app.all('/secret', function (req, res, next) {
  res.send('GET request to the secret section');
  console.log('Accessing the secret section ...');
  next(); // pass control to the next handler
});

Routing path

Routing paths and request methods together define the endpoints of requests, which can be strings, string patterns, or regular expressions.

Examples of routing paths using strings:

// Requests matching root paths
app.get('/', function (req, res) {
  res.send('root');
});

// Requests matching / about paths
app.get('/about', function (req, res) {
  res.send('about');
});

// Request matching / random.text path
app.get('/random.text', function (req, res) {
  res.send('random.text');
});

Examples of routing paths using string mode:

// Matching acd and abcd
app.get('/ab?cd', function(req, res) {
  res.send('ab?cd');
});

// Matching/abe and/abcde
app.get('/ab(cd)?e', function(req, res) {
 res.send('ab(cd)?e');
});

// Match abcd, abbcd, abbbcd, etc.
app.get('/ab+cd', function(req, res) {
  res.send('ab+cd');
});

// Match abcd, abxcd, abRABDOMcd, ab123cd, etc.
app.get('/ab*cd', function(req, res) {
  res.send('ab*cd');
});

Examples of routing paths using regular expressions:

// Match any path containing a:
app.get(/a/, function(req, res) {
  res.send('/a/');
});

// Match butterfly, dragonfly, mismatch butterfly man, dragonfly man, etc.
app.get(/.*fly$/, function(req, res) {
  res.send('/.*fly$/');
});

Routing handle handler

Can't set headers after they are sent.

You can provide multiple callback functions for request processing that behave like middleware. The only difference is that these callbacks are likely to call the next('route') method and skip other routing callbacks. This mechanism can be used to define the preconditions for routing. If it is meaningless to continue executing on the existing path, control can be transferred to the remaining path.

Routing handles come in many forms, such as a function, an array of functions, or a mixture of the two, as shown below.

Use a callback function to process routing:

app.get('/example/a', function (req, res) {
  res.send('Hello from A!');
});

Use multiple callback functions to handle routing (remember to specify next objects):

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!');
});

Use callback function arrays to process routing:

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]);

Mixed use of functions and function arrays for routing:

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!');
});

Response method res

The method of response object (res) in the following table returns the response to the client, terminating the loop of request response. If a method is not invoked in the routing handle, the request from the client will remain pending.

app.route()

You can use app.route() to create chain routing handles for routing paths. Because paths are specified in one place, this helps create modular routes and reduces code redundancy and spelling errors.

app.route('/book')
  .get(function(req, res) {
    res.send('Get a random book');
  })
  .post(function(req, res) {
    res.send('Add a book');
  })
  .put(function(req, res) {
    res.send('Update the book');
  });

express.Router

You can use the express.Router class to create modular, mountable routing handles.

The following example program creates a routing module, loads a middleware, defines some routes, and mounts them on the application path.

Create a file named birds.js under the app directory, which reads as follows:

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

// Middleware for this routing
router.use(function timeLog(req, res, next) {
  console.log('Time: ', Date.now());
  next();
});
// Define the route of the website homepage
router.get('/', function(req, res) {
  res.send('Birds home page');
});
// Define routes for about pages
router.get('/about', function(req, res) {
  res.send('About birds');
});

module.exports = router;

After loading the routing module in the application, the application can process requests from / birds and / birds/about, and call the timeLog middleware specified for the routing.

var birds = require('./birds');
...
app.use('/birds', birds);

3. Middleware

http://www.expressjs.com.cn/g...

Middleware List: https://github.com/senchalabs...

Express is a simple web development framework composed of routing and middleware: essentially, an Express application is calling various middleware.

Middleware is a function that can access request objects (req), response objects (res), and Middleware in the request-response loop process of web applications. It is generally named as next variable.

The functions of middleware include:

  • Execute any code.

  • Modify request and response objects.

  • End the request-response loop.

  • Call the next Middleware in the stack.

Note: If the current middleware does not terminate the request-response cycle, the next() method must be called to give control to the next middleware, otherwise the request will hang.

app.use

app.use([path], function)

Use the given middleware function, with optional mount path, defaulting to "/".

A middleware processor, the request comes, let those middleware first process again

  • There is no middleware with a mount path, and each request of the application executes the middleware.

  • Middleware mounted to / path, which is executed by any request to / path

Middleware Classification

Express applications can use the following middleware:

  • Application-level Middleware

  • Routing Level Middleware

  • Error Handling Middleware

  • Built-in Middleware

  • Third-party Middleware

1. Application-level Middleware

Application-level middleware binds to app objects using app.use() and app.METHOD(), where METHOD is the method of HTTP requests to be processed, such as GET, PUT, POST, etc., all lowercase. For example:

var app = express();

// There is no middleware with a mount path, and each request of the application executes the middleware.
app.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

// Middleware mounted to / user/:id will execute any request to / user/:id
app.use('/user/:id', function (req, res, next) {
  console.log('Request Type:', req.method);
  next();
});

// Routing and handle functions (middleware systems) handle GET requests to / user/:id
app.get('/user/:id', function (req, res, next) {
  res.send('USER');
});

// A middleware stack that prints out relevant information for any HTTP request pointing to / user/:id
app.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();
});

2. Routing Middleware

Like application middleware, routing middleware binds express.Router(). router.use() or router.VERB() is used to load the routing level.

The above middleware system created at the application level can be rewritten to the routing level by the following code:

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

// A middleware without a mount path is executed for every request through that route
router.use(function (req, res, next) {
  console.log('Time:', Date.now());
  next();
});

// A middleware stack that displays any HTTP request to / user/:id
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 stack that handles GET requests to / user/:id
router.get('/user/:id', function (req, res, next) {
  // If user id is 0, jump to the next route
  if (req.params.id == 0) next('route');
  // Responsible for handing control over to the next Middleware in the stack
  else next(); //
}, function (req, res, next) {
  // Rendering regular pages
  res.render('regular');
});

// Processing / user/:id, rendering a special page
router.get('/user/:id', function (req, res, next) {
  console.log(req.params.id);
  res.render('special');
});

// Mount routing to application
app.use('/', router);

3. Error Handling Middleware

http://www.expressjs.com.cn/g...

Error handling middleware is similar to other middleware definitions except that four parameters (err, req, res, next) must be used. Even if the next object is not needed, it must be declared in the signature, otherwise the middleware will be recognized as a regular middleware and cannot handle errors.

Error handling middleware should be loaded after other app.use() and routing calls, such as:

var bodyParser = require('body-parser');
var methodOverride = require('method-override');

app.use(bodyParser());
app.use(methodOverride());
app.use(function(err, req, res, next) {
  // Business logic
  console.error(err.stack);
  res.status(500).send('Something broke!');
});

The response returned by middleware is arbitrary. It can respond to an HTML error page, a simple sentence, a JSON string, or whatever you want.

To facilitate organization (higher-level frameworks), you may define multiple error-handling middleware just as you would define regular middleware. For example, if you want to define a request that uses XHR and a definition that is not used, then:

var bodyParser = require('body-parser');
var methodOverride = require('method-override');

app.use(bodyParser());
app.use(methodOverride());
app.use(logErrors);
app.use(clientErrorHandler);
app.use(errorHandler);

// logErrors writes requests and error messages to standard error output, logs, or similar services:
function logErrors(err, req, res, next) {
  console.error(err.stack);
  next(err);
}

// clientErrorHandler is defined as follows (note that errors are passed directly to next):
function clientErrorHandler(err, req, res, next) {
  if (req.xhr) {
    res.status(500).send({ error: 'Something blew up!' });
  } else {
    next(err);
  }
}

// Error Handler captures all errors, which are defined as follows:
function errorHandler(err, req, res, next) {
  res.status(500);
  res.render('error', { error: err });
}

4. Built-in Middleware

Express's previously built-in middleware is now installed and used as a separate module

express.static is Express's only built-in middleware, which is based on service-static and responsible for hosting static resources in Express applications.

5. Third-party Middleware

Third-party middleware list: http://www.expressjs.com.cn/r...

The following example installs and loads a middleware for parsing cookies: cookie-parser

$ npm install cookie-parser
var express = require('express');
var app = express();
var cookieParser = require('cookie-parser');

// Loading middleware for parsing cookie s
app.use(cookieParser());

4. Managing static files

Express built-in express.static can easily host static files, such as pictures, CSS, JavaScript files, etc.

Passing the directory where the static resource file is located as a parameter to express.static middleware can provide access to the static resource file.

Use

The path of all files is relative to the directory where they are stored, so the directory name where static files are stored does not appear in the URL.

Assuming you have images, CSS, and JavaScript files in the public directory, you can:

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

Now, the files under the public directory are accessible.

If your static resources are stored under multiple directories, you can call express.static middleware many times:

When accessing static resource files, express.static middleware finds the required files in the order in which directories are added.

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

If you want all files accessed through express.static to be stored in a virtual directory (that is, directory does not exist at all), you can specify a mount path for the static resource directory, as follows:

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

Now, you can access the files under the public directory through the address with the / static prefix.

__dirname

Within any module file, you can use the u dirname variable to get the complete absolute path of the directory where the current module file is located.

console.log(__dirname);

path.join()

Arguments to path.join must be strings

Combining multiple parameters into a path, syntax:

path.join([path1], [path2], [...])

Because this method belongs to path module, it is necessary to introduce path module before using it.

const express = require('express');
const path = require('path');

var app = express();

app.set('views', path.join(__dirname, 'views'));

app.use(express.static(path.join(__dirname, 'public')));

5. Using Template Engine in Express

Install the corresponding template engine npm package without requiring ('pug') on the page.

$ npm install pug --save

Write template files

html
  head
    title!= title
  body
    h1!= message

Then create a routing to render the template file, which will be rendered as HTML. If view engine is not set, you need to specify the suffix of the view file, otherwise it will be omitted.

  • views A directory for storing template files

  • view engine Register Template Engine

const express = require('express');

let app = express();

// view engine setup
app.set('views', ['./v']);
app.set('view engine', 'pug');

// http://localhost:3000/index
app.get('/index', function(req, res) {
  res.render('index', {
    title: 'Hey',
    message: 'view engine, Hello there!'
  });
});

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

let server = app.listen(3000, function() {
    let host = server.address().address;
    let port = server.address().port;

    console.log(`app listening at port: ${port}`);
});

6. Express 4 migration

http://www.expressjs.com.cn/g...

Express 4 is a disruptive change to Express 3, which means that if you update Express, the Express 3 application will not work.

1. Improvement of Express Kernel and Middleware System

Express 4 no longer relies on Connect and removes all built-in middleware except express.static from the kernel.

That is to say, Express is now an independent routing and middleware Web framework, and the version upgrade of Express is no longer affected by middleware updates.

After removing the built-in middleware, you must explicitly add all the middleware needed to run the application. Please follow the following steps:

  1. Installation module: NPM install -- save < module-name >

  2. Introduce modules in applications: require('module-name')

  3. Use modules as described in the document: app.use(...)

The following table lists the corresponding Middleware in Express 3 and Express 4:

2. Routing System

Applications now implicitly load routing middleware, so there is no need to worry about the loading order of router middleware to routing middleware.

The way routing is defined remains unchanged, but the new routing system has two new functions to help you organize routing:

  • A new class express.Router was added to create mountable modular routing handles.

  • A new method, app.route(), was added to create chain routing handles for routing paths.

3. Other changes

Function

node .

transfer

Unload Express 3 Application Generator:

$ npm uninstall -g express

Then install the new generator:

$ npm install -g express-generator

Tags: node.js npm JSON Web Development Javascript

Posted on Wed, 26 Dec 2018 13:30:06 -0800 by TheRealPenguin