Express: Node.js 用の Web アプリケーション フレームワーク Express は、簡潔で柔軟な Node.js Web アプリケーション開発フレームワークで、さまざまな Web アプリケーションやモバイル デバイス アプリケーションの作成に役立つ一連の強力な機能を提供します。
目次
この記事は、Express4.x (具体的には 4.10.4) の開発フレームワークに焦点を当てており、Mongoose、Ejs、Bootstrap およびその他の関連コンテンツも含まれます。
プロジェクトの作成
ディレクトリ構造
Express4.x 設定ファイル
Ejs テンプレートの使用法
ブートストラップ インターフェイス フレームワーク
ルーティング関数
セッションの使用状況
ページのヒント
ページアクセス制御
開発環境:
Ubuntu
MonogoDB: v2.6.4
nodejs:v0.11.2
npm 2.1.10 (nodejs がバージョン 1.2.19 でインストールされている場合、この記事はバージョン 2.x にアップグレードされています)
1. プロジェクトを作成します
プロジェクトディレクトリを入力してください
mkdir 職場
CD 職場
Express をグローバルにインストールします。Express はコマンドとしてシステムにインストールされます。
npm install -g Express
高速バージョンを表示
特急 -V
注: Express コマンドは、express4.x バージョンには含まれなくなりました。
express-generator をインストールする必要があります
npm install Express-generator -g
インストールプロセスの詳細については、「Nodejs 開発環境 Ubuntu の準備」を参照してください。
Express コマンドを使用してプロジェクトを作成し、ejs をサポートします
hadoop@sven:~/workspace/nodeJs$ Express -e nodejs-demo
作成:nodejs-demo (プロジェクト名)
create:nodejs-demo/package.json (プロジェクトパッケージ情報)
作成:nodejs-demo/app.js (メインプログラム)
作成:nodejs-demo/public (パブリックディレクトリ)
作成:nodejs-demo/public/images
作成:nodejs-demo/public/javascripts
作成:nodejs-demo/public/stylesheets
作成:nodejs-demo/public/stylesheets/style.css
create:nodejs-demo/routes (ルーティングディレクトリ。後でこのディレクトリでプログラムを開発し、app.js で使用します)
作成:nodejs-demo/routes/index.js
作成:nodejs-demo/routes/users.js
create:nodejs-demo/views (ディレクトリの表示、テンプレート ファイルの表示など)
作成:nodejs-demo/views/index.ejs
作成:nodejs-demo/views/error.ejs
作成:nodejs-demo/bin
作成:nodejs-demo/bin/www (app.js の起動に使用される起動ファイル)
依存関係をインストールします:
$ cd nodejs-demo && npm install
アプリを実行します:
$ DEBUG=nodejs-demo ./bin/www
プロジェクトは正常に作成されました。
上記のヒントに従って依存関係をインストールします:
プロンプトに従って Web を開始します:
ただし、ここではこの方法を使用してプログラムを開始するつもりはありません。その理由は、開発プロセス中にツールとしてnodemonを使用する必要があるためです。
Nodemon は、開発プロセス中にプロジェクトの変更を動的に識別し、それらを動的にロードするために使用されます (これは Eclipse の Java Web 開発に似ています)。このツールはウェブ開発に不可欠です
nodemon をインストールします:
npm install nodemon -g
それでは、上記の ./bin/www スクリプトを使用してみてはいかがでしょうか?
その理由は、nodemon ./bin/www にはプロジェクトの変更を識別する方法がないためです。 (私自身が実験してみました。詳しい方がいらっしゃいましたらアドバイスをお願いします)
app.js を変更します:
最後の行 //module.exports = app をコメントアウトします
次のように置き換えられました: app.listen(3000);
次のコマンドを使用して、app.js メイン プログラムを開始します:
hadoop@sven:~/workspace/nodeJs/nodejs-demo$ nodemon app.js
次にプログラムを変更して、動的にロードされるかどうかを確認します。次のプロンプトが表示されます:
12 月 1 日 16:22:07 – [nodemon] 変更により再起動中…
12 月 1 日 16:22:07 – [nodemon] `node app.js`
は有効になることを意味します。
テスト:
ローカル ポート 3000 が開かれ、ブラウザ経由でアクセスされます: localhost:3000
2. ディレクトリ構造
./
drwxrwxr-x 5 hadoop hadoop 4096 12 月 1 日 15:57 ../
-rw-rw-r– 1 hadoop hadoop 1495 12 月 1 日 16:22 app.js
-rw-r–r– 1 hadoop hadoop 12288 12 月 1 日 16:22 .app.js.swp
drwxr-xr-x 2 hadoop hadoop 4096 12 月 1 日 15:57 bin/
drwxrwxr-x 9 hadoop hadoop 4096 12 月 1 日 15:58 node_modules/
-rw-rw-r– 1 hadoop hadoop 326 12 月 1 日 15:57 package.json
drwxr-xr-x 5 hadoop hadoop 4096 12 月 1 日 15:57 public/
drwxr-xr-x 2 hadoop hadoop 4096 12 月 1 日 15:57 ルート/
drwxr-xr-x 2 hadoop hadoop 4096 12 月 1 日 15:57 ビュー/
ディレクトリの紹介:
node_modules、すべてのプロジェクト依存ライブラリを保存します。 (各プロジェクトは独自の依存関係を管理します。これは Maven や Gradle などとは異なります)
package.json、プロジェクトの依存関係構成と開発者情報
app.js、プログラムのメインエントランス
パブリック、静的ファイル (css、js、img)
ルート、ルーティング ファイル (C、MVC のコントローラー)
ビュー、ページ ファイル (Ejs テンプレート)
nodejs-demo/bin/www (起動ファイル、app.js の起動に使用)
app.js を開いてコンテンツを表示します:
/** * 模块依赖 */ 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. Ejs テンプレートの使用法
ejs テンプレート ファイルには拡張子が html のファイルを使用します。
変更: app.js
var ejs = require('ejs'); //ejs を導入します。依存関係を再インストール>
app.engine('.html', ejs.__express);
app.set('ビュー エンジン', 'html'); // app.set('ビュー エンジン', 'ejs');
名前を変更: views/*.ejs から views/*.html
localhost:3000 へのアクセスは正しいです
主にindex.ejsなどのファイル名を変更します
5. ブートストラップ インターフェイス フレームワークを追加します
実際には、js ファイルと css ファイルをプロジェクト内の対応するディレクトリにコピーするだけです。 4 つのファイルが含まれています:
public/stylesheets ディレクトリにコピー
bootstrap.min.css
ブートストラップレスポンシブ.min.css
public/javascripts ディレクトリにコピーします
bootstrap.min.js
jquery-1.9.1.min.js
次に、index.html ページを header.html、index.html、footer.html の 3 つの部分に分割します
header.html、HTML ページのヘッダー領域です
index.html、コンテンツ表示領域
footer.html は、ページの下部領域です
header.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>
localhost:3000 へのアクセスは正しいです。
EJS テンプレートの機能を使用して、公開ヘッダーとフッターをページから分離することに成功しました。
そして、ブートストラップ インターフェイス フレームワークが導入されました。
6. ルーティング機能
ユーザー ログインのビジネス要件を設計しましょう。
アクセスパス:/、ページ:index.html、ログイン不要で直接アクセスできます。
アクセスパス:/home、ページ:home.html、アクセスする前にユーザーはログインする必要があります。
アクセスパス:/login、ページ:login.html、ログインページ、ユーザー名とパスワードを正しく入力すると、自動的にhome.htmlにジャンプします
アクセスパス: /logout、ページ: なし ログアウト後、自動的にindex.htmlページに戻ります
app.js ファイルを開き、ルーティング構成を追加します
app.get('/',routes.index); app.route('/login') .get(routes.login) post(routes.doLogin); app.get('/logout',routes.logout); app.get('/home',routes.home);
注: get は取得リクエスト、post はポストリクエスト、all はこのパスに対するすべてのリクエストです
routes/index.js ファイルを開き、対応するメソッドを追加します。
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}); };
views/login.html と views/home.html の 2 つのファイルを作成します
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 %>
index.html を変更し、ログイン リンクを追加します
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页面,<%- message %>
<% 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,页面本来是登陆以后才访问的,现在我们不要登陆,直接在浏览器输入也可访问。
页面报错了,提示<%= user.username %> 变量出错。
GET /home?user==a 500 15ms
TypeError: D:\workspace\project\nodejs-demo\views\home.html:2
1| <% include header.html %>
>> 2|
这个页面被打开发,因为没有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开发框架随手笔记,希望大家喜欢。