Express learning notes

Get started quickly

a. Install express, currently using version 4.17.

Enter the following command in the terminal:

yarn add express

b. Create an 'app JS' file, introduce express, create an Express instance, and listen to port 3000.

//app.js
const express = require('express');

const app = express();

app.listen(3000, () => {
  console.log('running at http://localhost:3000');
});

Enter the following command in the terminal:

yarn add nodmon #Used to update node code in real time
nodemon app.js # Start running code

c. When the client accesses http://localhost:3000 The res.send() method can be used to return the content of the get request to the client.

const express = require('express');

const app = express();

app.get('/', (req, res) => {
  // Send status code
  res.send('hi express')
});


app.listen(3000, () => {
  console.log('running at http://localhost:3000');
});

Or use res.json({name:'jiaqi'}). Here, because I installed the JSON plug-in, the data style is beautified a little.

You can also send a return file to the client, res.download('img.png '), because I really have a picture here. When the client accesses the website, you can download the file.

d. If you want to set the status code for, you can use res.sendStatus(500).

However, if you want to send content while setting the status code, you can use res.status (500) send('server error').

Alternatively, you can use res.status (500) json (message: 'error'), data in json format will be sent.

template engine

Rendering html using ejs

If you want to render html on the client side, you can use view engine, where you will use the npm package ejs.

yarn add ejs #Install ejs

And on app JS set ejs as view engine.

const express = require('express');

const app = express();

app.set('view engine', 'ejs');

app.get('/', (req, res) => {
  
});


app.listen(3000, () => {
  console.log('running at http://localhost:3000');
});

Then we create a view folder in the root directory to store the html folder that needs to be rendered.

Then change the html suffix to ejs

Then, in order to have the functions of code highlighting and syntax completion in ejs files, you can install an ejs plug-in.

Then add a sentence in the code, app Render (the html name under the view folder), and you will see hello on the client.

app.get('/', (req, res) => {
  res.render('index');
});

Pass information to html

Through the second parameter of render function, we can pass information to our html file

app.get('/', (req, res) => {
  res.render('index',{name:'jiaqi'});
});

In ejs, <%% > is equivalent to the slot {}} in vue, which means js is used here, and = means output in html.

Therefore, the screenshot above finally displays in the browser:

Next, if you want to use the server, the data passed to the template engine is the same.

But if we pass too many variables to the template, we don't remember whether to pass them in the end. For example, we didn't pass the variable name333 to the template engine here, and finally the browser reported an error.

To solve this problem, we add a locals before the variable in the ejs file. Without name333, the browser will not display and report errors!

`

route

If there are a hundred paths, we can't write them all in the app JS, which is difficult to maintain. Of course, express also thought of this. We can use routing, which allows us to create another instance with its own logic, and then finally we can embed these codes into our main code.

A router object is an isolated instance of middleware and routes You can think of it as a “mini-application,” capable only of performing middleware and routing functions. Every Express application has a built-in app router.

For example, I wrote many paths related to users here. We can put these codes into the routes folder.

const express = require('express');

const app = express();

app.set('view engine', 'ejs');

app.get('/', (req, res) => {
  res.render('index',{name:'jiaqi'});
});

//users
app.get('/users', (req, res) => {
  res.send('user list');
})
app.get('/users/new', (req, res) => {
  res.send('user new form');
})

//===users


app.listen(3000, () => {
  console.log('running at http://localhost:3000');
});

Create a folder of routes under the root directory and create users JS file.

Then in user JS, introduce express, use its Router() function, and then add app Replace get() with router get().

//routes/users.js
const express = require('express');
const router = express.Router();


router.get('/users', (req, res) => {
  res.send('user list');
})
router.get('/users/new', (req, res) => {
  res.send('user new form');
})

Next, we export the router object and remove the / users in front of these paths (because we will deal with them later when we introduce these users routes in app.js)

//routes/users.js
const express = require('express');
const router = express.Router();


router.get('/', (req, res) => {
  res.send('user list');
})
router.get('/new', (req, res) => {
  res.send('user new form');
});


module.exports = router;

Now on app JS to introduce the users route just exported.

//app.js

const express = require('express');

const app = express();

app.set('view engine', 'ejs');

app.get('/', (req, res) => {
  res.render('index',{name:'jiaqi'});
});

//Use user routing
//It means to take / users as the starting point of the path, and then connect/ routes/user.js file
app.use('/users', require('./routes/user'));


app.listen(3000, () => {
  console.log('running at http://localhost:3000');
});

At this time, when we open the corresponding website, it will still display normally.

Dynamic routing

Suppose we have many users now, such as' / users/1 ',' users/2 ',' users/3 ', etc. But we can't create a route for every user's request address!

At this time, we can use dynamic routing, router Get ('/: ID'), by using:, tell express to match any parameter suffix.

//routes/users.js

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


router.get('/', (req, res) => {
  res.send('user list');
})
router.get('/new', (req, res) => {
  res.send('user new form');
});

router.get('/:id', (req, res) => {
  // The id in the path here is user-defined
  // If it is defined as /: userid and you want to get the corresponding userid, use req params. userId
  res.send(`Get user ${req.params.id}Data`);
})



module.exports = router;

NOTE: NOTE that dynamic routing should generally be placed at the bottom, because express matches the request path from top to bottom.

Suppose here, I put / new under dynamic routing

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


router.get('/', (req, res) => {
  res.send('user list');
})


router.get('/:id', (req, res) => {
  // The id in the path here is user-defined
  // If it is defined as /: userid and you want to get the corresponding userid, use req params. userId
  res.send(`Get user ${req.params.id}Data`);
})

router.get('/new', (req, res) => {
  res.send('user new form');
});

module.exports = router;

We can see that /: id also matches the path of '/ new', because id is just a name. It can match any string, including new.

app.route()

If a path needs both get and put and delete, we can use app Route() is called chained. In routing, the app Replace route() with route route()

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


router.get('/', (req, res) => {
  res.send('user list');
})



router.route('/:id')
  .get((req, res) => {
    res.send(`get user with id ${req.params.id}`);
  })
  .put((req, res) => {
    res.send(`update user with id ${req.params.id}`);
  })
  .delete((req, res) => {
    res.send(`delete user with id ${req.params.id}`);
  })


module.exports = router;

In this way, we will write the path a few times less!

app.param(name,callback)

As above, write router in routing param(). It means that if the path of each route matches the app The first parameter of param (that is, name) executes the subsequent callback function.

The parameters in the callback function are the request object, the response object, the next middleware, the value of the parameter and the name of the parameter, that is, app param(name,callback(req,res,next,id,name))

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


router.get('/', (req, res) => {
  res.send('user list');
})



router.route('/:id')
  .get((req, res) => {
    res.send(`get user with id ${req.params.id}`);
  })
  .put((req, res) => {
    res.send(`update user with id ${req.params.id}`);
  })
  .delete((req, res) => {
    res.send(`delete user with id ${req.params.id}`);
  })

// If the id in the path is matched, this function is executed
// The above get, put and delete all have the parameter id
router.param('id', (req, res, next, id, name) => {
  console.log(id, name); //The console prints 2, id
})


module.exports = router;

But the browser has been circling, indicating that it is loading and the page has not been refreshed!

This is because we did not call the next function to perform the next step. Because router Param () is essentially a kind of middleware. The middleware is that after the request is sent to the server, but the server has not returned the response to the client.

This middleware is then invoked to actually correspond to the routing (if next() is invoked in this middleware).

If the attribute is attached to the req or res of the middleware at this time, the subsequent routes can access it

router.get('/:id', (req, res) => {
   //Here you can get the user attribute just added on req
  console.log(req.user)
  res.send(`user's id is ${req.params.id}`);
})

const users = [{ name: 'jiaqi' }, { name: 'sally' }];

router.param('id', (req, res, next, id) => {
  //Next, other routes can access the user attribute added at this time
  req.user = users[id]
  next();
})

middleware

If there is a function that needs to be used for each path, you can use app at the top Use () defines a middleware. Middleware runs from top to bottom.

Never forget that middleware functions need to call next().

const express = require('express');

const app = express();

app.set('view engine', 'ejs');
app.use(logger); //middleware 


app.get('/', (req, res) => {
  res.render('index',{text:'world'});
})

const userRouter = require('./routes/users')
app.use('/users', userRouter);

function logger(req, res, next) {
  console.log(req.originalUrl);
  next()
}


app.listen(3000, () => {
  console.log('running at http://localhost:3000');
});

In addition to using app Use () uses middleware. You can also use middleware directly before a route.

app.get('/',logger, (req, res) => {
  res.render('index',{text:'world'});
})

If you like, you can also use multiple middleware functions in the same path.

app.get('/',logger, logger, (req, res) => {
  res.render('index',{text:'world'});
})

Render static files

express comes with some practical middleware, such as rendering static files.

For example, in the public folder under the root directory, we put some static HTML files, and we won't modify the HTML content.

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

At this time, even if we don't write any route, it can directly render the index in the public folder html.

const express = require('express');

const app = express();

app.set('view engine', 'ejs');

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

app.listen(3000, () => {
  console.log('running at http://localhost:3000');
});

If you create a new folder test under the public folder, and then create an index under the test folder html, and then if we visit: http://localhost:3000/test/ You can also open the html file.

In short, the url will correspond to the actual storage path of the file one by one.

Parse form

If we want to get the form information submitted by others, we can use this middleware:

app.use(express.urlencoded({extended:true}));

After that, we can pass req Body gets the information submitted by the user.

Suppose the form is:

<form action="/users" method="post">
    <input type="text" name="userName" id="name" value="<%=locals.name %>">
  <button type="submit">Submit</button>
</form>

Get form information:

router.get('/new', (req, res) => {
  res.render('users/new',{name:'jiaqi'}) //The second parameter passes parameters to the template engine
})

router.post('/', (req, res) => {
  console.log(req.body); //Get the form information submitted by the user
  res.send('create user');
})

Parsing JSON

This is the same as the parsing form above. The difference is that the parsing form above is used to parse the user's request in JSON format.

app.use(express.json())

Keywords: Javascript node.js Front-end

Added by l_evans on Mon, 31 Jan 2022 11:32:40 +0200