Get to know Express
- concept
Official: Based on node JS platform, a fast, open and minimalist Web development framework
Popular understanding: the role of Express and node JS is similar to the built-in http module, which is specially used to create a Web server.
- With http module, why use Express
http built-in module is very complex to use and has low development efficiency; Express is further encapsulated based on the built-in http module, which can greatly improve the development efficiency.
Using Express, you can easily and quickly create a Web site server or an API interface server.
- Basic use
- Listen for GET and POST requests
const express = require('express') //Create web server const app = express(); //Listen to the GET and POST requests of the client. The refrigerator client responds to the specific content. The first parameter is the URL app.get('/user', (req, res) => { //Call the res.send() method provided by express to respond to a JSON object to the client res.send({name : 'ZS', age: 20, gender : 'male'}) }) app.post('/user', (req, res) => { //Call the res.send() method provided by express to respond to a text string to the client res.send('Request succeeded') }) // Start the web server app.listen(80, () => { console.log('express server running at http://127.0.0.1') })
- Get the query parameters carried in the URL
Through req Query object, which can access the parameters sent to the server by the client in the form of query string
const express = require('express') //Create web server const app = express(); app.get('/', (req, res) => { //Through req Query object, which can get the parameters sent from the client //Note that by default, req Query is an empty object console.log(req.query) res.send(req.query) }) // Start the web server app.listen(80, () => { console.log('express server running at http://127.0.0.1') })
Send a GET request on Postman, and the result is:
Get the query parameters carried in the URL
- Get dynamic parameters in URL
Through req Params object, which can be accessed in the URL through: matching parameters
Specific code
const express = require('express') //Create web server const app = express(); //Note: id here is a dynamic parameter app.get('/user/:id', (req, res) => { //req.query is a dynamic match to an empty object console.log(req.params) res.send(req.params) }) // Start the web server app.listen(80, () => { console.log('express server running at http://127.0.0.1') })
result:
- Managed static resources
Via express Static () makes it easy to create a static resource server
Note: Express finds files in the specified static directory and provides access paths to external resources. Therefore, the name of the directory where the static files are stored will not appear in the URL.
const express = require('express') //Create web server const app = express(); //Here, call express The static () method can provide static resources quickly app.use(express.static('./clock')) app.listen(80, () =>{ console.log('express server running at http://127.0.0.1') })
Hosting multiple static resource directories
Call express multiple times Just use the static() function
app.use(express.static('./clock')) app.use(express.static('./files'))
When accessing static resource files, express The static () function looks for the required files according to the order in which the directories are added
Mount path prefix
app.use('/abc', express.static('./files'))
Install nodemon
npm i -g nodemon
Replace the node command with the nodemon command and use nodemon to start the project. In this way, after the code is modified, it will be monitored by nodemon, so as to realize the effect of automatically restarting the project.
Express routing
- Concept of routing
Routing in Express refers to the mapping relationship between the client's request and the server's processing function
The Express middle route consists of three parts: the type of request, the URL address of the request, and the processing function
app.METHOD(PATH, HANDLER)
Precautions for route matching:
① Match according to the defined order
② The request type and the requested URL match successfully at the same time,
The corresponding processing function will be called
- Use of routing
The simplest usage
const express = require('express') const app = express() // Mount routing app.get('/', (req, res) => { res.send('hello world.') }) app.post('/', (req, res) => { res.send('Post Request.') }) app.listen(80, () => { console.log('http://127.0.0.1') })
Modular routing
Specific steps:
① Create the corresponding routing module js file
② Call express The router() function creates a routing object
③ Mount a specific route to the routing object
④ Use module Exports share routing objects outward
⑤ Use app The use() function registers the routing module
const express = require('express') //Create routing object const router = express.Router() //Mount specific routes router.get('/user/list', (req, res) => { res.send('Get user list') }) router.post('/user/add', (req, res) => { res.send('Add new user') }) //Export routing objects outward module.exports = router
Register routing module
//Import routing module const router = require('./03router') //Register routing module app.use(router)
Prefix routing module
//Import routing module const router = require('./03router') //Register routing module app.use('/api', router)
middleware
Basic concepts
After a request arrives at the Express server, multiple middleware can be called continuously to preprocess the request
The middleware of Express is essentially a function processing function
The next function is the key to realize the continuous call of multiple middleware. It means to transfer the flow relationship to the next middleware or route.
Initial experience of Middleware
- Define middleware functions
const express = require('express') const app = express() //Define the simplest middleware function const mw = function(req, res, next){ next(); } app.listen(80, () => { console.log('http://127.0.0.1') })
Globally effective Middleware
const express = require('express') const app = express() //Define the simplest middleware function const mw = function(req, res, next){ next(); } //Register mw as a globally effective Middleware app.use(mw) app.get('/', (req, res) => { res.send('Home page') }) app.get('/user', (req, res) => { res.send('User page') }) app.listen(80, () => { console.log('http://127.0.0.1') })
- Role of Middleware
Multiple middleware share the same req and res. Based on this feature, we can uniformly add req or res objects in the upstream middleware
Add custom attributes or methods for downstream middleware or routing.
code:
const express = require('express') const app = express() app.use((req, res, next) => { //Gets the time when the request arrived const time = Date.now() //Mount custom attributes for req objects to share time with all subsequent routes req.startTime = time next(); }) app.get('/', (req, res) => { res.send('Home page' + req.startTime) }) app.get('/user', (req, res) => { res.send('User page' + req.startTime) }) app.listen(80, () => { console.log('http://127.0.0.1') })
- Define multiple global Middleware
You can use app Use() defines multiple global Middleware in succession. After the client request arrives at the server, it will be called in the order defined by the middleware.
const express = require('express') const app = express() //Define global Middleware app.use((req, res, next) => { console.log('The first global middleware was called') next(); }) app.use((req, res, next) => { console.log('The second global middleware is called') next(); }) //Define route app.get('/user', (req, res) => { res.send('User page' ) }) app.listen(80, () => { console.log('http://127.0.0.1') })
- Partially effective Middleware
Don't use app The middleware defined by use () is called locally effective middleware
const express = require('express') const app = express() const mw1 = (req, res, next) => { console.log('Partial effective middleware was called') next(); } //Create route app.get('/', mw1,(req, res) => { //mw1 middleware is only effective in the current route. This usage belongs to the middleware with local effectiveness res.send('Home page') }) app.get('/user', (req, res) => { res.send('User page' ) }) app.listen(80, () => { console.log('http://127.0.0.1') })
- Define multiple local Middleware
//These two expressions are completely equivalent app.get('/', mw1, mw2,(req, res) => { res.send('Home page') }) app.get('/', [mw1, mw2], (req, res) => { res.send('Home page') }
- Five considerations of Middleware
- Be sure to register the middleware before routing
- The request sent by the client can be processed by calling multiple middleware continuously (the calling order is the defined order)
- After executing the business code of the middleware, don't forget to call the next() function
- In order to prevent code logic confusion, do not write other additional code
- When multiple middleware are called continuously, req and res objects are shared among multiple middleware
Classification of Middleware
① Application level Middleware
Via app Use () or app Get () or app Post (), the middleware bound to the app instance, is called application level middleware
② Routing level Middleware
Bind to express The middleware on the router () instance is called the routing level middleware. Its usage is no different from that of application level middleware. However, the application level middleware is bound to the app instance, and the routing level middleware is bound to the router instance
③ Error level Middleware
Function of error level middleware: it is specially used to capture abnormal errors in the whole project, so as to prevent the abnormal collapse of the project.
Format: in the function processing function of the error level middleware, there must be four formal parameters, which are (err, req, res, next) from front to back.
be careful! Error level middleware must be registered after all routes
Code implementation:
const express = require('express') const app = express() // Define route app.get('/', (req, res) => { throw new Error('An error occurred inside the server') res.send('Home page.') }) //Middleware defining error levels app.use((err, req, res, next) => { console.log('An error has occurred' + err.message) res.send('Error' + err.message) }) app.listen(80, () => { console.log('http://127.0.0.1') })
Test results:
④ Express built-in Middleware
-
express.static is a built-in middleware that quickly manages static resources, such as HTML files, pictures, CSS styles, etc. (no compatibility)
-
express.json parsing request body data in JSON format (compatible, only available in version 4.16.0 +)
-
express.urlencoded parses the request body data in URL encoded format (compatible, only available in version 4.16.0 +)
First, express. Com is introduced with an example json
const express = require('express') const app = express() //Via express JSON () is a middleware that parses JSON in forms app.use(express.json()) app.post('/user', (req, res) => { //On the server, you can use req The body attribute is used to receive the request sent by the client //By default, if the middleware for parsing form data is not configured, req The default value of body is undefined console.log(req.body) res.send('OK.') }) app.listen(80, () => { console.log('http://127.0.0.1') })
Introduce express with examples urlencoded
const express = require('express') const app = express() app.use(express.urlencoded({extended: false})) app.post('/book', (req, res) => { console.log(req.body) res.send('OK') }) app.listen(80, () => { console.log('http://127.0.0.1') })
⑤ Third party Middleware
The middleware, which is not officially built in but developed by a third party, is called third-party middleware. In the project, you can download and configure the third-party middleware as needed, so as to improve the development efficiency of the project
Custom Middleware
Manually simulate a similar to express Middleware such as urlencoded is used to parse the form data submitted to the server by POST.
Implementation steps:
① Define Middleware
② Listen for data events of req
③ Listen for the end event of req
④ Use the querystring module to parse the request body data
⑤ Mount the parsed data object as req body
⑥ Encapsulate custom middleware into modules
const express = require('express') const app = express() //Import self encapsulated middleware module const customBodyParser = require('./12custom-body-parser') //Register the customized middleware functions as globally available middleware app.use(customBodyParser) app.post('/user', (req, res) =>{ console.log('req.body') }) app.listen(80, () => { console.log('Express server running at http://127.0.0.1') })
Customized middleware 12custom-body-parser js
const qs = require('querystring') //Middleware for parsing form data const bodyParser = ((req, res, next) =>{ //Define the specific business logic of Middleware //str is used to define a special data string sent by the client let str = '' //2. Listen to the data event of req req.on('data',(chunk) =>{ //Splice request body data, implicitly converted to string str += chunk }) //3. Listen to the end event of req req.on('end', () =>{ //Parse the request body data in string format into object format const body = qs.parse(str) req.body = body next() }) }) module.exports = bodyParser
Using Express write interface
Create basic server and API routing module
const exp = require('constants') const express = require('express') const app = express() const router = require('./14apiRouter') // Mount routing app.use('/api', router) app.listen(80, () => { console.log('Express server running at http://127.0.0.1') })
const express = require('express') const router = express.Router() module.exports = router
GET interface and POST interface
const exp = require('constants') const express = require('express') const app = express() //Configure middleware for parsing form data app.use(express.urlencoded({extended :false})) const router = require('./14apiRouter') // Mount routing app.use('/api', router) app.listen(80, () => { console.log('Express server running at http://127.0.0.1') })
const express = require('express') const router = express.Router() //Define get interface router.get('/get', (req, res) => { // Through req Query gets the data sent to the server by the client through the query string const query = req.query //Call the res.send() method to respond to the processing results to the client res.send({ status: 0 , //0 indicates successful processing and 1 indicates failed processing mag : 'GET Request succeeded',//Description of status data: query //Data required to respond to the client }) }) //Define post interface router.post('/post', (req, res) => { const body = req.body res.send({ status: 0 , //0 indicates successful processing and 1 indicates failed processing mag : 'POST Request succeeded',//Description of status data: body }) }) module.exports = router
There are two main solutions to interface cross domain problems:
-
CORS (mainstream solution, recommended)
-
JSONP (defective solution: only GET requests are supported)
CORS cross domain resource sharing
cors is a third-party middleware of Express. Cross domain problems can be easily solved by installing and configuring cors middleware.
1. The use steps are divided into the following three steps:
① Run npm install cors to install Middleware
② Import middleware using const cors = require('cors')
③ Call app before routing Use (cors()) configuration Middleware
2. Precautions for CORS
① CORS is mainly configured on the server side. The client browser can request to open the CORS interface without any additional configuration.
② CORS is compatible in browsers. Only browsers that support XMLHttpRequest Level 2 can normally access the server interface with CORS enabled (e.g. IE10 +, Chrome4 +, Firefox 3.5 +)
- CORS response header
If the value of the access control allow origin field is specified as a wildcard *****, it means that requests from any domain are allowed
res.setHeader('Access-Control-Allow-Origin','*')
By default, CORS only supports the client to send the following 9 request headers to the server:
Accept, accept language, content language, DPR, Downlink, save data, viewport Width, Width, content type (values are limited to one of text/plain, multipart / form data, application/x-www-form-urlencoded)
If the client sends additional request header information to the server, you need to declare the additional request header on the server through access control allow headers, otherwise the request will fail!
res.setHeader('Access-Control-Allow-Headers','Content-Type','X-Custom-Header')
By default, CORS only supports GET, POST and HEAD requests initiated by clients.
If the client wants to request the resources of the server through PUT, DELETE, etc., it needs to indicate the HTTP method allowed by the actual request through access control alow methods on the server side.
res.setHeader('Access-Control-Allow-Methods','DELETE','HEAD')
- Classification of CORS requests
When the client requests the CORS interface, according to the different request methods and request headers, the CORS requests can be divided into two categories, namely:
① Simple request
② Pre inspection request
Simple request
A request that meets both of the following two conditions is a simple request:
① Request method: one of GET, POST and HEAD
② HTTP header information does not exceed the following fields: no custom header field, Accept, Accept language, content language, DPR, Downlink, save data, viewport Width, Width, content type (only three values: application/x-www-form-urlencoded, multipart / form data, text/plain)
Pre inspection request
As long as the request meets any of the following conditions, a pre inspection request is required:
① The request Method is the request Method type other than GET, POST and HEAD
② The request header contains a custom header field
③ Sent data in application/json format to the server
Before the formal communication between the browser and the server, the browser will send an OPTION request for pre check to know whether the server allows the actual request. Therefore, this OPTION request is called "pre check request". After the server successfully responds to the pre inspection request, it will send the real request and carry the real data
Difference between simple request and pre inspection request
Characteristics of simple request: only one request will occur between the client and the server.
Characteristics of pre check request: there will be two requests between the client and the server. After the pre check request of OPTION is successful, the real request will be initiated
JSONP
The browser side requests the data on the server through the src attribute of the < script > tag, and the server returns a function call. This way of requesting data is called JSONP.
- characteristic:
① JSONP is not a real Ajax request because it does not use the XMLHttpRequest object.
② JSONP only supports GET requests, not POST, PUT, DELETE and other requests
- Precautions for creating JSONP interface
If CORS cross domain resource sharing has been configured in the project, in order to prevent conflicts, the JSONP interface must be declared before configuring CORS middleware. Otherwise, the JSONP interface will be processed as an interface with CORS enabled
- Implementation steps
① Get the name of the callback function sent by the client
② Get the data to be sent to the client in the form of JSONP
③ According to the data obtained in the first two steps, splice a function call string
④ The string spliced in the previous step is sent to the client