Maison  >  Article  >  interface Web  >  Cadre de développement Nodejs Express4.x notes_node.js

Cadre de développement Nodejs Express4.x notes_node.js

WBOY
WBOYoriginal
2016-05-16 15:30:411353parcourir

Express : cadre d'application Web pour Node.js Express est un cadre de développement d'applications Web node.js concis et flexible. Il fournit une série de fonctionnalités puissantes pour vous aider à créer diverses applications Web et pour appareils mobiles.

Table des matières

Cet article se concentre sur le cadre de développement d'Express4.x (en particulier 4.10.4), qui implique également Mongoose, Ejs, Bootstrap et d'autres contenus connexes.

Créer un projet
Structure du répertoire
Fichier de configuration Express4.x
Utilisation du modèle Ejs
Cadre d'interface Bootstrap
Fonction de routage
Utilisation de la session
Conseils pour les pages
Contrôle d'accès aux pages

Environnement de développement :

Ubuntu

MonogoDB : v2.6.4

nodejs:v0.11.2

npm 2.1.10 (Si nodejs est installé avec la version 1.2.19, cet article a été mis à niveau vers la version 2.x)

1. Créer un projet

Entrez le répertoire du projet

lieu de travail mkdir

lieu de travail cd

Installez Express globalement et Express est installé dans le système en tant que commande.

npm install -g express

Voir la version express

exprimer -V

Remarque : La commande express n'est plus incluse dans la version express4.x.

Besoin d'installer un générateur express

npm install express-generator -g

Pour le processus d'installation détaillé, voir : "Préparation de l'environnement de développement Nodejs Ubuntu"

Utilisez la commande express pour créer un projet et prendre en charge les ejs

hadoop@sven:~/workspace/nodeJs$ express -e nodejs-demo

créer : nodejs-demo (nom du projet)
create : nodejs-demo/package.json (informations sur le package du projet)
créer : nodejs-demo/app.js (programme principal)
create : nodejs-demo/public (répertoire public)
créer : nodejs-demo/public/images
créer : nodejs-demo/public/javascripts
créer : nodejs-demo/public/stylesheets
créer : nodejs-demo/public/stylesheets/style.css
create : nodejs-demo/routes (répertoire de routage, développez des programmes dans ce répertoire plus tard, puis utilisez-le dans app.js)
créer : nodejs-demo/routes/index.js
créer : nodejs-demo/routes/users.js
créer : nodejs-demo/views (répertoire de visualisation, fichiers de modèle de visualisation, etc.)
créer : nodejs-demo/views/index.ejs
créer : nodejs-demo/views/error.ejs
créer : nodejs-demo/bin
create : nodejs-demo/bin/www (fichier de démarrage, utilisé pour démarrer app.js)
installer les dépendances :
$ cd nodejs-demo && npm install
lancez l'application :
$ DEBUG=nodejs-demo ./bin/www

Projet créé avec succès.

Installez les dépendances selon les conseils ci-dessus :

Copier le code Le code est le suivant :

cd nodejs-demo && npm install

Démarrez le Web en fonction des invites :

Copier le code Le code est le suivant :

$DEBUG=nodejs-demo ./bin/www

Cependant, nous n'allons pas utiliser cette méthode pour démarrer le programme ici. La raison en est que nous devons utiliser nodemon comme outil pendant le processus de développement.
Nodemon est utilisé pour identifier dynamiquement les modifications du projet pendant le processus de développement, puis les charger dynamiquement (cela est similaire au développement Web Java d'Eclipse). Cet outil est indispensable au développement web

Installer nodemon :

npm install nodemon -g

Alors pourquoi n'utilisons-nous pas le script ./bin/www ci-dessus ?

La raison est que nodemon ./bin/www n'a aucun moyen d'identifier les modifications du projet. (J'ai personnellement expérimenté. S'il y a des experts qui savent, merci de me donner quelques conseils)

Modifier app.js :

Commentez la dernière ligne //module.exports = app

Remplacé par : app.listen(3000);

Utilisez la commande suivante pour démarrer le programme principal app.js :

hadoop@sven:~/workspace/nodeJs/nodejs-demo$ nodemon app.js

Modifiez ensuite le programme pour voir s'il sera chargé dynamiquement. L'invite suivante s'affichera :

1 décembre 16:22:07 – [nodemon] redémarrage en raison de changements…
1er décembre 16:22:07 – [nodemon] démarrage de `node app.js`

signifie prendre effet.

Test :

Le port local 3000 est ouvert et accessible via le navigateur : localhost:3000

2. Structure du répertoire

./
drwxrwxr-x 5 hadoop hadoop 4096 1 décembre 15:57 ../
-rw-rw-r– 1 hadoop hadoop 1495 1er décembre 16:22 app.js
-rw-r–r– 1 hadoop hadoop 12288 1er décembre 16:22 .app.js.swp
drwxr-xr-x 2 hadoop hadoop 4096 1er décembre 15:57 bin/
drwxrwxr-x 9 hadoop hadoop 4096 1er décembre 15:58 node_modules/
-rw-rw-r– 1 hadoop hadoop 326 1 décembre 15:57 package.json
drwxr-xr-x 5 hadoop hadoop 4096 1er décembre 15:57 public/
drwxr-xr-x 2 hadoop hadoop 4096 1er décembre 15:57 routes/
drwxr-xr-x 2 hadoop hadoop 4096 1 décembre 15:57 vues/

Présentation de l'annuaire :

node_modules, stocke toutes les bibliothèques dépendantes du projet. (Chaque projet gère ses propres dépendances, ce qui est différent de Maven, Gradle, etc.)
package.json, configuration des dépendances du projet et informations sur le développeur
app.js, entrée principale du programme
fichiers publics et statiques (css, js, img)
routes, fichier de routage (C, contrôleur en MVC)
Vues, ​​fichier d'échange (modèle Ejs)
nodejs-demo/bin/www (fichier de démarrage, utilisé pour démarrer app.js)

Ouvrez app.js pour afficher le contenu :

/**
* 模块依赖
*/
var express = require('express')
, routes = require('./routes')
, user = require('./routes/user')
, http = require('http')
, path = require('path');
var app = express();
//环境变量
app.set('port', process.env.PORT || 3000);
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.favicon());
app.use(express.logger('dev'));
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(express.static(path.join(__dirname, 'public')));
// 开发模式
if ('development' == app.get('env')) {
app.use(express.errorHandler());
}
// 路径解析
app.get('/', routes.index);
app.get('/users', user.list);
// 启动及端口
http.createServer(app).listen(app.get('port'), function(){
console.log('Express server listening on port ' + app.get('port'));
});

4. Utilisation du modèle Ejs

Laissez le fichier modèle ejs utiliser un fichier avec l'extension html.

Modifier : app.js

var ejs = require('ejs'); //Introduire ejs. Réinstaller les dépendances>
app.engine('.html', ejs.__express);
app.set('afficher le moteur', 'html'); // app.set('afficher le moteur', 'ejs');
Renommer : views/*.ejs en vues/*.html

L'accès à localhost:3000 est correct

Renommer principalement les fichiers tels que index.ejs

5. Ajouter le framework d'interface Bootstrap

En fait, copiez simplement les fichiers js et css dans le répertoire correspondant dans le projet. Comprend 4 fichiers :

Copier dans le répertoire public/stylesheets

bootstrap.min.css
bootstrap-responsive.min.css

Copier dans le répertoire public/javascripts

bootstrap.min.js
jquery-1.9.1.min.js

Ensuite, nous divisons la page index.html en 3 parties : header.html, index.html, footer.html

header.html, est la zone d'en-tête de la page html
index.html, est la zone d'affichage du contenu
footer.html, est la zone inférieure de la page

en-tête.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><%=: title %></title>
<!-- Bootstrap -->
<link href="http://www.geedoo.info/stylesheets/bootstrap.min.css" rel="stylesheet" media="screen">
<!-- <link href="http://www.geedoo.info/css/bootstrap-responsive.min.css" rel="stylesheet" media="screen"> -->
</head>
<body screen_capture_injected="true">
index.html
<% include header.html %>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
<% include footer.html %>
footer.html
<script src="http://www.geedoo.info/javascripts/jquery-1.9.1.min.js"></script>
<script src="http://www.geedoo.info/javascripts/bootstrap.min.js"></script>
</body>
</html>

L'accès à localhost:3000 est correct.

Nous avons utilisé avec succès la fonction des modèles EJS pour séparer l'en-tête et le pied de page publics de la page.

Et le framework d'interface bootstrap a été introduit.

6. Fonction de routage

Définissons les exigences commerciales de connexion des utilisateurs.

Chemin d'accès : /, page : index.html, aucune connexion requise, accessible directement.
Chemin d'accès : /home, page : home.html, l'utilisateur doit se connecter avant d'accéder.
Chemin d'accès : /login, page : login.html, page de connexion, saisissez correctement le nom d'utilisateur et le mot de passe et accédez automatiquement à home.html
Chemin d'accès : /logout, page : Aucun Après vous être déconnecté, vous reviendrez automatiquement à la page index.html

.

Ouvrez le fichier app.js et ajoutez la configuration du routage

app.get('/',routes.index);
app.route('/login')
.get(routes.login)
post(routes.doLogin);
app.get('/logout',routes.logout);
app.get('/home',routes.home);

Remarque : get est une demande d'obtention, post est une demande de publication, et all sont toutes des demandes pour ce chemin

Nous ouvrons le fichier routes/index.js et ajoutons la méthode correspondante.

exports.index=function(req, res) {
 res.render('index', { title: 'index' });
};
exports.login=function(req,res){
 res.render('login',{title: '用户登录'});
};
exports.doLogin=function(req,res){
 var user = {
 username:"admin",
 password:"admin"
}
if(req.body.username==user.username && req.body.password==user.password){
 res.redirect('/home');
}
res.redirect('/login');
};
exports.logout = function(req,res){
 res.redirect('/');
};
exports.home = function(req,res){
 var user = {
 username:'admin',
 password:'admin'
 }
 res.render('home',{title:'Home',user:user});
};

Créez deux fichiers, vues/login.html et vues/home.html

login.html

<% include header.html %> 
<div class="container-fluid">
<form class="form-horizontal" method="post">
<fieldset>
<legend>用户登陆</legend>
<div class="control-group">
<label class="control-label" for="username">用户名</label>
<div class="controls">
<input type="text" class="input-xlarge" id="username" name="username">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">密码</label>
<div class="controls">
<input type="password" class="input-xlarge" id="password" name="password">
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">登陆</button>
</div>
</fieldset>
</form>
</div>
<% include footer.html %>
home.html:
<% include header.html %>
<h1>Welcome <%= user.username %>, 欢迎登陆!!</h1>
<a claa="btn" href="http://www.geedoo.info/logout">退出</a>
<% include footer.html %>

Modifiez index.html et ajoutez un lien de connexion

index.html

<% include header.html %>
<h1>Welcome to <%= title %></h1>
<p><a href="http://www.geedoo.info/login">登陆</a></p>
<% include footer.html %>

路由及页面我们都写好了,快去网站上试试吧。

7. Session使用

从刚来的例子上面看,执行exports.doLogin时,如果用户名和密码正确,我们使用redirect方法跳转到的home

res.redirect('/home');

执行exports.home时,我们又用render渲染页面,并把user对象传给home.html页面

res.render('home', { title: 'Home',user: user});

为什么不能在doLogin时,就把user对象赋值给session,每个页面就不再传值了。

session这个问题,其实是涉及到服务器的底层处理方式。

像Java的web服务器,是多线程调用模型。每用户请求会打开一个线程,每个线程在内容中维护着用户的状态。

像PHP的web服务器,是交行CGI的程序处理,CGI是无状态的,所以一般用cookie在客户的浏览器是维护用户的状态。但cookie在客户端维护的信息是不够的,所以CGI应用要模仿用户session,就需要在服务器端生成一个session文件存储起来,让原本无状态的CGI应用,通过中间文件的方式,达到session的效果。

Nodejs的web服务器,也是CGI的程序无状态的,与PHP不同的地方在于,单线程应用,所有请求都是异步响应,通过callback方式返回数据。如果我们想保存session数据,也是需要找到一个存储,通过文件存储,redis,Mongdb都可以。

接下来,我将演示如何通过mongodb来保存session,并实现登陆后用户对象传递。

app.js文件

在相应位置添加下面代码:

var session = require('express-session');
var connect = require('connect');
var SessionStore = require("session-mongoose")(connect);
var store = new SessionStore({
url:"mongodb://localhost/session",
 interval: 120000
});
app.use(session({
 secret: 'test.com',
 store: store,
 cookie:{maxAge:10000} //expire session in 10 seconds
}));
//用于把登录用户设置到res.locals里面,在home.html里显示
app.use(function(req,res,next){
 res.locals.user = req.session.user;
 console.log('Session is = ',req.session.user);
 next();
});

需要添加中间件connect、session-mongoose。

其中session-mongoose是用于连接mongodb数据库。然后自动写入session信息到数据库中(也可以用mongoose中间件,但是要自己实现session的写入)

app.use(session(….)) 这里是全局设置了session的信息及session信息存储的方式。

注:app.js文件有顺序要求,一定要注意!!!

安装session-mongoose依赖库

npm install connect

npm install session-mongoose

npm install session-mongoose

安装有错误但是没关系。

访问:http://localhost:3000/login,正常

修改routes/index.js文件

exports.doLogin方法

exports.doLogin = function(req, res){
 var user={ username:'admin', password:'admin' } 
 if(req.body.username===user.username && req.body.password===user.password){ 
  req.session.user=user; 
  return res.redirect('/home');
 } else { 
  return res.redirect('/login'); 
 }
};

exports.logout方法

exports.logout = function(req, res){
 req.session.user=null;
 res.redirect('/');
};

exports.home方法

exports.home = function(req, res){
 res.render('home', { title: 'Home'});
};

这个时候session已经起作用了,exports.home的user显示传值已经被去掉了。 是通过app.js中app.use的res.locals变量,通过框架进行的赋值。

app.use(function(req, res, next){
 res.locals.user = req.session.user;
 next();
});

注:这个session是express4.10.4的写法,与express4之前的版本是不一样的。

访问页面可以查看mongodb有没有数据:

nodejs-mongodb
nodejs-mongodb

由于上面配置的 cookie:{maxAge:10000} //expire session in 10 seconds
过期时间,因此你会看到mongodb里面的数据过一段时间就被清除了。
参考:

Mongoose:http://mongoosejs.com/

关于express4.2.0与express3.x操作的区别:http://blog.csdn.net/u013758116/article/details/38758351

8. 页面提示

登陆的大体我们都已经讲完了,最后看一下登陆失败的情况。

我们希望如果用户登陆时,用户名或者密码出错了,会给用户提示,应该如何去实现。

打开app.js的,增加res.locals.message

登陆的大体我们都已经讲完了,最后看一下登陆失败的情况。

我们希望如果用户登陆时,用户名或者密码出错了,会给用户提示,应该如何去实现。

打开app.js的,增加res.locals.message

app.use(function(req, res, next){
 res.locals.user = req.session.user;
 var err = req.session.error;
 delete req.session.error;
 res.locals.message = '';
 if (err) res.locals.message = '<div class="alert alert-danger">' + err + '</div>';
 next();
});

修改login.html页面,f7e1051a7314c7d7c4371c24ffe6d522

<% include header.html %>
<div class="container-fluid">
<form class="form-horizontal" method="post">
<fieldset>
<legend>用户登陆</legend>
<%- message %>
<div class="control-group">
<label class="control-label" for="username">用户名</label>
<div class="controls">
<input type="text" class="input-xlarge" id="username" name="username" value="admin">
</div>
</div>
<div class="control-group">
<label class="control-label" for="password">密码</label>
<div class="controls">
<input type="password" class="input-xlarge" id="password" name="password" value="admin">
</div>
</div>
<div class="form-actions">
<button type="submit" class="btn btn-primary">登陆</button>
</div>
</fieldset>
</form>
</div>
<% include footer.html %>

修改routes/index.js,增加req.session.error

exports.doLogin = function(req, res){
 var user={
 username:'admin',
 password:'admin'
 }
 if(req.body.username===user.username && req.body.password===user.password){
 req.session.user=user;
 return res.redirect('/home');
 } else {
 req.session.error='用户名或密码不正确';
 return res.redirect('/login');
 }
};

让我们来看看效果: http://localhost:3000/login 输入错误的和密码, 用户名:dad,密码:da

boostrap-nodejs

9. 页面访问控制

网站登陆部分按照我们的求已经完成了,但网站并不安全。

localhost:3000/home,页面本来是登陆以后才访问的,现在我们不要登陆,直接在浏览器输入也可访问。

页面报错了,提示ba980d12e5b7c2433035a997a636db0b 变量出错。

GET /home?user==a 500 15ms
TypeError: D:\workspace\project\nodejs-demo\views\home.html:2
1| bd8252839a1160287e059aba355d0851
>> 2| 4a249f0d628e2318394fd9b75b4636b1Welcome ba980d12e5b7c2433035a997a636db0b, 欢迎登陆!!473f0a7621bec819994bb5020d29372a
3| 3776e88ac50f1d21a105088d366d11bd退出5db79b134e9f6b82c0b36e0489ee08ed
4| bd8252839a1160287e059aba355d0851
Cannot read property 'username' of null
at eval (eval at 8299e0e36aa4be98b826c9c76c3775f0 (D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:
at eval (eval at 8299e0e36aa4be98b826c9c76c3775f0 (D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:
at D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:249:15
at Object.exports.render (D:\workspace\project\nodejs-demo\node_modules\ejs\lib\ejs.js:287:
at View.exports.renderFile [as engine] (D:\workspace\project\nodejs-demo\node_modules\ejs\l
at View.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\view.js:75:8)
at Function.app.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\applicati
at ServerResponse.res.render (D:\workspace\project\nodejs-demo\node_modules\express\lib\res
at exports.home (D:\workspace\project\nodejs-demo\routes\index.js:36:8)
at callbacks (D:\workspace\project\nodejs-demo\node_modules\express\lib\router\index.js:161

这个页面被打开发,因为没有user.username参数。我们避免这样的错误发生。

还记录路由部分里说的get,post,all的作用吗?我现在要回到路由配置中,再做点事情。

修改app.js文件

app.get('/',routes.index);
app.route('/login')
.all(notAuthentication)
.get(routes.login)
.post(routes.doLogin);
app.route('/logout')
app.get('/',routes.index);
app.route('/login')
.all(notAuthentication)
.get(routes.login)
.post(routes.doLogin);
app.route('/logout')
.get(authentication)
.get(routes.logout);
app.route('/home')
.get(authentication)
.get(routes.home);

访问控制:

/ ,谁访问都行,没有任何控制
/login,用all拦截所有访问/login的请求,先调用authentication,用户登陆检查
/logout,用get拦截访问/login的请求,先调用notAuthentication,用户不登陆检查
/home,用get拦截访问/home的请求,先调用Authentication,用户登陆检查
修改app.js文件,增加authentication,notAuthentication两个方法

function authentication(req, res, next) {
 if (!req.session.user) {
 req.session.error='请先登陆';
 return res.redirect('/login');
 }
 next();
}
function notAuthentication(req, res, next) {
 if (req.session.user) {
  req.session.error='已登陆';
  return res.redirect('/home');
 }
 next();
}

配置好后,我们未登陆,直接访问localhost:3000/home时或者localhost:3000/logout,就会跳到/login页面

登录后, 访问localhost:3000/login 则直接跳到/home页面

到此,express4 相关内容到此为止。

以上内容是小编给大家分享的Nodejs Express4.x开发框架随手笔记,希望大家喜欢。

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn