新手学习node和使用express遇到问题求助

Node.js(9)
&&&&&& 在学校NodeJS中遇到了各种各样的问题,尤其是因为版本更新,而产生的一些包的不兼容问题,下面写一下关于Express遇到的问题。
首先引用别人的一下总结:
&&&&&& node的安装分为全局模式和本地模式。
一般情况下会以本地模式运行,包会被安装到和你的应用程序代码的本地node_modules目录下。
在全局模式下,Node包会被安装到Node的安装目录下的node_modules下。
全局安装命令为$npm install -g moduleName。
获知使用$npm set global=true来设定安装模式,$npm get global可以查看当前使用的安装模式。
npm install express
默认会安装express的最新版本,也可以通过在后面加版本号的方式安装指定版本,如npm install express@3.0.6
npm install &name& -g
将包安装到全局环境中
但是代码中,直接通过require()的方式是没有办法调用全局安装的包的。全局的安装是供命令行使用的,就好像全局安装了vmarket后,就可以在命令行中直接运行vm命令
npm install &name& --save
安装的同时,将信息写入package.json中项目路径中如果有package.json文件时,直接使用npm install方法就可以根据dependencies配置安装所有的依赖包,这样代码提交到github时,就不用提交node_modules这个文件夹了。
2、npm view moduleNames:查看node模块的package.json文件夹
注意事项:如果想要查看package.json文件夹下某个标签的内容,可以使用$npm view moduleName labelName
3、npm list:查看当前目录下已安装的node包
注意事项:Node模块搜索是从代码执行的当前目录开始的,搜索结果取决于当前使用的目录中的node_modules下的内容。$ npm list parseable=true可以目录的形式来展现当前安装的所有node包
4、npm help:查看帮助命令
5、npm view moudleName dependencies:查看包的依赖关系
6、npm view moduleName repository.url:查看包的源文件地址
7、npm view moduleName engines:查看包所依赖的Node的版本
8、npm help folders:查看npm使用的所有文件夹
9、npm rebuild moduleName:用于更改包内容后进行重建
10、npm outdated:检查包是否已经过时,此命令会列出所有已经过时的包,可以及时进行包的更新
11、npm update moduleName:更新node模块
12、npm uninstall moudleName:卸载node模块
13、一个npm包是包含了package.json的文件夹,package.json描述了这个文件夹的结构。访问npm的json文件夹的方法如下:
$ npm help json
此命令会以默认的方式打开一个网页,如果更改了默认打开程序则可能不会以网页的形式打开。
14、发布一个npm包的时候,需要检验某个包名是否已存在
$ npm search packageName
15、npm init:会引导你创建一个package.json文件,包括名称、版本、作者这些信息等
16、npm root:查看当前包的安装路径
npm root -g:查看全局的包的安装路径
17、npm -v:查看npm安装的版本
&&&&& 以上是在网上查找的一些资料。在学习Express框架时,我们一般是建立本地模块,安装方法为
首先编写一空的package.json。这样但你安装模块是,它会自动加依赖添加进去。
安装Express模块:G:\nodejs\MongodeTest&npm install express --save
这样在你的工程下就好建立一个node_modules文件夹,express就安装在里面。
&&&& 一般Express团队维护了一个可以快速生成项目模板的可执行文件,
安装方法:G:\nodejs\MongodeTest&npm install -g express-generator
这样我们就可以用express来管理了:如查看express版本:
G:\nodejs\MongodeTest&express -V
&&&&&&& 这个工具提供了一个非常简单的生成一个程序骨架的功能,但是它也有局限,比如它只支持很少的几个模板引擎。而事实上Express几乎支持所有的为node所建的模板引擎。使用
--help查看一下帮助:
Usage: express [options]
-h, --help
输出帮助信息
-V, --version
输出版本号
添加 ejs 模板引擎支持 (默认为jade)
-H, --hogan
添加 hogan.js模板引擎支持
样式 &引擎& 支持 (less|stylus) (默认为css)
-f, --force
强制在非空目录执行
如果你想生成一个支持Jade, Stylus的应用程序,只需要简单的执行下面的命令:
express --sessions --css stylus --ejs myapp
create : myapp
create : myapp/package.json
create : myapp/app.js
create : myapp/public
create : myapp/public/javascripts
create : myapp/public/images
create : myapp/public/stylesheets
create : myapp/public/stylesheets/style.styl
create : myapp/routes
create : myapp/routes/index.js
create : myapp/views
create : myapp/views/index.jade
create : myapp/views/layout.jade
install dependencies:
$ cd myapp && npm install
run the app:
$ DEBUG=myapp node app
和其它node程序一样,你必须安装依赖:
$ cd myapp
$ npm install
然后让我们运行它吧!
错误处理的中间件和普通的中间件定义是一样的,只是它必须有4个形参,这是它的形式:(err, req, res, next):
app.use(function(err, req, res, next){
console.error(err.stack);
res.send(500, 'Something broke!');
一般来说非强制性的错误处理一般被定义在最后,下面的代码展示的就是放在别的app.use() 之后:
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(function(err, req, res, next){
在这些中间件里的响应是可以任意定义的。只要你喜欢,你可以返回任意的内容,譬如HTML页面, 一个简单的消息,或者一个JSON字符串。
对于一些组织或者更高层次的框架,你可能会像定义普通的中间件一样定义一些错误处理的中间件。假设你想定义一个中间件区别对待通过XHR和其它请求的错误处理,你可以这么做:
app.use(express.bodyParser());
app.use(express.methodOverride());
app.use(app.router);
app.use(logErrors);
app.use(clientErrorHandler);
app.use(errorHandler);
通常logErrors用来纪录诸如stderr, loggly, 或者类似服务的错误信息:
function logErrors(err, req, res, next) {
console.error(err.stack);
next(err);
clientErrorHandler 定义如下,注意错误非常明确的向后传递了。
function clientErrorHandler(err, req, res, next) {
if (req.xhr) {
res.send(500, { error: 'Something blew up!' });
next(err);
下面的errorHandler &捕获所有& 的异常, 定义为:
function errorHandler(err, req, res, next) {
res.status(500);
res.render('error', { error: err });
在线用户计数
这一小节我们讲解一个小而全的应用程序,它通过记录在线用户数。首先你需要创建一个package.json 文件,包含两个依赖,一个是redis 客户端,另一个是Express。另外需要确认你安装了redis, 可以能过执行$ redis-server来确认:
&name&: &app&,
&version&: &0.0.1&,
&dependencies&: {
&express&: &3.x&,
&redis&: &*&
接下来你需要你创建一个应用程序,和一个redis连接:
var express = require('express');
var redis = require('redis');
var db = redis.createClient();
var app = express();
接下来是纪录用户在线的中间件。这里我们使用sorted sets, 它的一个好处是我们可以查询最近N毫秒内在线的用户。我们通过传入一个时间戳来当作成员的&score&。注意我们使用 User-Agent 作为一个标识用户的id。
app.use(function(req, res, next){
var ua = req.headers['user-agent'];
db.zadd('online', Date.now(), ua, next);
下一个中间件是通过zrevrangebyscore来查询上一分钟在线用户。我们将能得到从当前时间算起在60,000毫秒内活跃的用户。
app.use(function(req, res, next){
var min = 60 * 1000;
var ago = Date.now() -
db.zrevrangebyscore('online', '+inf', ago, function(err, users){
if (err) return next(err);
req.online =
最后我们来使用它,绑定到一个端口!这些就是这个程序的一切了,在不同的浏览器里访问这个应用程序,你会看到计数的增长。
app.get('/', function(req, res){
res.send(req.online.length + ' users online');
app.listen(3000);
给Express加一层代理
在Express的前端使用一个反向代理,比如 Varnish 或者 Nginx是非常常见的,它不需要额外的配置。在通过app.enable('trust proxy')激活了&trust proxy& 设置后,Express 就会知道它在一个代理的后面,X-Forwarded-* 必须被信任,通常情况下这些头是很容易被伪装的。
使用了这个设置后会有一些很棒的小变化。 首先由代理设置的X-Forwarded-Proto 会告诉程序它是https 还是http 。这个值会影响.
第二个变化是
的值会被X-Forwarded-For列表里的地址取代。
调试 Express
Express使用
模块来输出信息。如果想看到这些信息,可以在运行你的程序时设置
DEBUG 环境变量为 express:* ,调试信息会输出在终端里 。
$ DEBUG=express:* node app.js
使用上面的方式运行 hello world 的例子,将会输出下面的内容
express:application booting in development mode +0ms
express:router defined get /hello.txt +0ms
express:router defined get /hello.txt +1ms
原文:http://expressjs.jser.us/guide.html
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:23256次
排名:千里之外
原创:22篇
转载:48篇
(2)(8)(10)(1)(19)(6)(1)(5)(2)(6)(11)(1)NodeJS框架express的HTTP方法和错误处理_javascript_ThinkSAAS
NodeJS框架express的HTTP方法和错误处理
NodeJS框架express的HTTP方法和错误处理
在CSSer前面的文章中我们已经接触过app.get()多次了,同时Express也提供了对其它HTTP动作的封装,如app.post(), app.del()等。
对于POST最常见的例子,就是当我们提交一个表单时,下面我们在HTML中将表单的method特性设置为“post”,然后需要在服务端定义对该表单提交的路由控制。
&form method="post"action="/"&
&input type="text"name="user[name]"/&
&input type="text"name="user[email]"/&
&input type="submit"value="Submit"data-description=""/&
默认情况下Express并不知道该如何处理该请求体,因此我们需要增加bodyParser中间件,用于分析application/x-www-form-urlencoded和application/json请求体,并把变量存入req.body。我们可以像下面的样子来“使用”中间件:
app.use(express.bodyParser());
接下来下面的路由就可以访问req.body.user对象了,该对象包含客户端提交的name和email属性。
app.post('/', function(req, res){
console.log(req.body.user);
res.redirect('back');
要在表单中使用PUT的HTTP方法,我们可以利用名为_method的隐藏表单域,它能改变HTTP方法。而在服务端,我们首先需要利用methodOverride中间件,把它放在bodyParser中间件下方,从而可以利用包含表单值的req.body。
app.use(express.bodyParser());
app.use(express.methodOverride());
之所以需要这样做,是因为这些处理并不总是默认进行的,原因很简单,因为这些对Express的整体功能来说并不是必需的,依据应用的具体需求,你并不一定需要这些功能,如果客户端直接支持PUT和DELETE方法也可以被直接访问到,同时methodOverride为表单提供了强大的解决方案,下面我们展示下PUT的使用:
&form method="post"action="/"&
&input type="hidden"name="_method"value="put"/&
&input type="text"name="user[name]"/&
&input type="text"name="user[email]"/&
&input type="submit"value="Submit"/&
app.put('/', function(){
console.log(req.body.user);
res.redirect('back');
Express提供了app.error()方法来接收路由或传入next(err)的异常,下面的示例为不同的页面提供专门的NotFound异常服务:
function NotFound(msg){
this.name = 'NotFound ';
Error.call(this, msg);
Error.captureStackTrace(this, arguments.callee);
NotFound.prototype.__proto__ = Error.
app.get('/404', function(req, res){
throw new NotF
app.get('/500', function(req, res){
throw new Error('keyboard cat!');
像下面一样,我们可以多次调用app.error(),这里我们检查如果是NotFound实例就显示404页面,否则将其传入下一个错误处理。
注意这些处理可以定义在任何地方,它们可以放在路由可以listen()之处。这也允许在configure()块内做定义,于是我们就可以以不同的基于环境的方式处理异常。
app.error(function(err, req, res, next){
if (err instanceof NotFound) {
res.render('404.jade');
next(err);
下面的演示我们假设所有错误都为500错误,但你可以根据喜好选择。例如当node在处理文件系统调用时,就有可能接收到这样的错误对象,其ENOENT的error.code为“no such file or directory”,这时我们可以在错误处理函数中进行处理然后显示特定的页面给用户。
app.error(function(err, req, res){
res.render('500.jade', { error: err });
我们的应用也可以利用Connect errorHandler中间件来汇报异常信息。例如我们想在“开发”环境输出异常到stderr:
app.use(express.errorHandler({ dumpExceptions: true }));
同时在开发期间我们想用好看的HTML页面显示异常信息时,可以设置showStack的值为true:
app.use(express.errorHandler({ showStack: true, dumpExceptions: true }));
如果请求头支持application/json,errorHandler中间件也能以json方式做出响应,这对依赖于客户端Javascript的应用开发很有益处。
PHP开发框架
开发工具/编程工具
服务器环境
ThinkSAAS商业授权:
ThinkSAAS为用户提供有偿个性定制开发服务
ThinkSAAS将为商业授权用户提供二次开发指导和技术支持
让ThinkSAAS更好,把建议拿来。
开发客服微信菜鸟学习Node.js--express(一)
什么是Express
Express 是一个简洁而灵活的 node.js Web应用框架, 提供了一系列强大特性帮助你创建各种 Web 应用,和丰富的 HTTP 工具。
不难发现我们可以因此而更快的开发一个网站,而且是在稳定,已经测试的代码之上编写应用程序
Express能做什么
1.基于json的API
2.单页面web应用程序
3.实时web应用程序
但是如果我们创建命令脚本的话,就不会使用他了
安装Express
在上一篇博客()讨论npm的全局安装,这里就不再介绍了。
再我们执行&npm install -g express&之后出现如下信息,则表示express安装成功。vcD4NCjxoMSBpZD0="创建demo">创建demo
创建Express站点
1.新建文件夹exress_demo,再文件夹内打开cmd.exe,输入
express epxress_example
我们会发现出现了那么多的create,那么就表示我们的基础站点已经创建成功。
3.当然人家还是很人性话的提示执行
cd express_example &&npm install,这句话的意思是安装运行Express所依赖的模块。
4.执行cd express_example &&npm install出现如下结果。
我们看一下我们的express_demo文件夹下是否又如下文件:
如果有,就表示我们创建成功了,那么我们现在打开app.js文件,在
module.exports = app 这行代码的上边加上app.listen(3000);,这样我们再cmd.exe的窗口中输入node app.js.
打开,输入,如果看到如下结果,那么恭喜,一个基础的Express我们就创建成功了。
探索Express
如我们的文件结构
用来启动程序的应用程序文件,他包含应用程序的配置信息
2. package.json
提供运行程序的信息,包含所需依赖的模块
定义应用程序的布局
公共文件夹,我们可以在里边看到js文件,图片等信息,
路由,我们下一篇博客再详细说
6. node_modules
存放package.json依赖的模块
view的jade文件
在view中我们会看到又一些jade文件,他利用Express模版为我们快速生成html文件,jade是基于缩进的模版,什么意思,给大家举个例子
例如我们再jade中写
那么会生成html中的
例如我们要给section标记一个ID,写法如下
section#wrapper&&
亦或者我们要添加一个class名称或者多个类名称
p.highlight&&
p.first.second.third&&
如果体现结构的话,我们需要缩进
Jade的优势是他不仅能够进行文件的结构,还能进行输出数据。
- var menghaibin = 'shuaige'
p I want to be #{menghaibin}
编译后就是I want to be shuaige
例如我们在view中的index.jade加入如下代码
- var menghaibin = 'shuaige'
h1.shuaige#demo 这就是个测试jade的demo
span I want to be #{menghaibin}
然后运行node app.js,但是运行之前大家可以想象一下结果是什么。
脑补完以后我们看一下结果。
生成的html
当然这里的缩进,如果是用的tab,都用tab,如果是空格,都用空格,否则会报错。jade还有循环,内联等,这里就不再一一说明了。
alert('Inline script in Jade')
- beatles = ['John', 'Paul', 'Ringo', 'George']
each beatle in beatles
li #{beatle}
结果什么样,大家可以自己尝试。
这篇博客,我们讨论了Express的作用和安装,我们还说了Jade这个模版的方便和使用,当然这还是入门,我们再说一遍,这篇博客只能是一个入门,但是这个入门非常的简单,相信可以让我们将node.js看成一个孩子吧,如果想让他长大,那么我们的路还很长。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'新手刚学nodejs 关于express的权限控制有问题请教各位大神 - CNode技术社区
这家伙很懒,什么个性签名都没有留下。
花了些时间初步了解了nodejs 和express 的运作方式.这几天准备做一个小的项目,在考虑到权限问题的时候却被卡住了.
我的需求是这样的. 单纯的用户认证这个应该很简单,passport这些都能胜任… 但是我想做的是针对每个请求URL进行权限控制.比如针对普通用户,
普通用户可以访问/user/updateSelf ,不能访问/user/addUser,而作为管理员可以访问任何一个链接. 这是第一方面
另外一方面,因为express也支持 restful的请求, 类似/user/:userId, /user/:action/:data ,如果采用这样的写法, 那么后台实际定义的URL是上面写的这样, 而接收过来的请求
URL 可能是 /user/12 , /user/save/u3 , 针对这样的URL 我又该怎么进行权限的控制呢.
我打算将所有定义的URL都和数据中的角色表进行映射, 比如 admin 对应 [/user/:userId,/user/:action/:data] 而普通用户角色 user对应 [/user/:userId]
那么 对于这样的路由 app.get(’/user/:action/:data’,function(res,req,next){…}) user就不会有权限访问.
但是我又该如何在处理请求之前获取 这些实际的url 诸如 /user/1 对应的是 /user/:userId 这个Url呢?
java中有反射,并且像struts这样的框架提供了拦截器,在执行action之前可以反射获取待执行的action,然后在判断URL和角色有无权限. 在nodejs中有这样的办法吗?
有人有好的办法吗 或者 有没有其他的权限控制框架.
让我不用为每个路由去配置权限. 而只要通过aop的方式,在执行所有的路由方法之前 判断权限?
我说一种比较常见的做法.
// 写一个验证middleware
var auth = function(req, res, next) {
var routePath=req.route.
// ....
app.get('/user/:action/:data’, auth,
function(req, res, next) {
//...
app.get('/user/:userId’, auth,
function(req, res, next) {
//...
这个我之前考虑过. 因为这样的写法还是得为每个路由手动在路由的声明上配置一个auth
因为路由是支持写多个function的. 所以我想有没有这样一种可能
假设原先路由是这样定义的.
app.get(’/user/:action/:data’,
function(req, res, next) {
app.get(’/user/:userId’,
function(req, res, next) {
那么有没有像java中反射那样的机制来获取我所定义路由中的分别对应的function或者function数组. 这样我只需要在初始化路由的时候.为每个路由都push一个或者多个新的权限认证函数进去,类似你的auth.
比如 获取路径对应路由定义的 function =
app.getRoutefunctions() 返回类似{path:’/user/:userId’,functions:[…一系列function]} 最后我只要遍历这个对象 functions.push(auth),这只是举例. 实际不知道有没有办法完成这样的功能.
如果能达到这样 我就不需要为每个路由都配置auth了
这边文章中说的和我的想法基本一样. 博主也提到了一个框架 sails 以及其中的sails-permissions
express中有无类似的中间件呢?
直接代码说话~
router.post('/post', checkLogin);
function checkLogin(req, res, next) {
if (!req.session.user) {
req.flash('error', '未登录!');
res.redirect('/login');
兄弟, 这样还是得为每个路由配置checkLogin. 我是想要那种aop 通过切面的方式注入进去那种方式,而不用为每个路由配置认证和权限.
那你这相当于要java里struts2的filter,那种貌似在session中存储权限列表,express里就在路由前加个中间件了
app.use(function(req, res, next) {
//判断当前访问url是否在权限列表
aop不是通常用来管理事务么…
也有用到拦截器啊,能获取控制器对象。
我就是想要拦截器的那种概念,要获取到控制器对象.
的想法.我是获取不到我要的控制器对象的.
这样restful形式的URL 我就没有办法获取到路由中定义的URL,比如/user/1 对应的/user/:userId 我只能获取到/user/1 而获取不到/user/:userId
另外我这样的想法确实是想吧权限放在session中, 每次执行都去判断权限.
这个也是中间件的一种呀,代码量虽然增加啦,但这个是自己可控,类似1楼的方法,在需要的地方添加。你可以直接用app.use自己写一个中间件也同理,但是用app.use真的是对每一个路由都验证,有些地方并不需要
Token认证:
if ((****dexOf(‘admin’) &= 0 && dbUser.role == ‘admin’) || (req.url.indexOf(‘admin’) & 0 && req.url.indexOf(’/api/v1/’) &= 0)) {
next(); // To move to next middleware
以下代码片段应该是你要的效果:
var myApp = angular.module(‘ngclient’, [‘ngRoute’]);
myApp.config(function($routeProvider, $httpProvider) {
$httpProvider.interceptors.push(‘TokenInterceptor’);
$routeProvider
.when(’/login’, {
templateUrl: ‘partials/login.html’,
controller: ‘LoginCtrl’,
requiredLogin: false
}).when(’/’, {
templateUrl: ‘partials/home.html’,
controller: ‘HomeCtrl’,
requiredLogin: true
开源博客系统liblog已经具备权限管理,方便可以自定义,并且开放源码,可以参照他看一下http://livisky.github.io/
我借鉴的是java中shiro框架的原理,数据库中存 role(角色表),func(权限表),user(用户表), role_func(角色权限的关联表), user_role(用户角色关联表),可以实现为不同的角色动态添加权限,然后在func表中添加每一个路由作为一个权限,自己写中间件进行验证,对于你说的/user/:userId类似于这种问题,在中间件中对于请求比如说 /user/23,将其中的数字替换成:userId,然后对照数据库检查中用户是否有这个权限,中间件做为权限校验
有没有源码开放,学习一下,谢谢
function(req, res, next){
console.log(req.route.path)
是可以得到/user/:id?的
express框架其实很多api都暴露出来了,比如app对象,就挂载在req.app上
所以呢,大概有两种方式实现你要的效果
胆子小一点:
把controller原始url表达式和对应的auth模块做一个映射公共方法
写的每一个路由函数里,根据req.route.path进行调用鉴权;
胆子大一点:
修改express框架源码里面的lib/router/route.js,大致看了下源码,在189行处,添加如下的代码:
var handles = flatten(slice.call(arguments));
//添加的代码如下:
var authArr = getAuth(this.path);
handles = authArr.concat(handles);
getAuth就是你自己写的根据设置的path规则返回的鉴权函数,此处需要返回一个数组,如下所示:
function getAuth(path){
if(path === '/user/:usrId?')
return [function auth1(){/*鉴权函数1*/}, function auth2(){/*鉴权函数2*/}];
//如果没有匹配到,则返回空数组,表示无需鉴权
return [];
这样就等于在每一个业务开发者编写的路由中,自动根据path注入你的映射公共方法,并且不同的路由可以注入不同的鉴权方法(一个或者多个),这样对于业务模块编写者来说感知不到,易用性会好一点
我是这样做的,写一个auth中间件,然后数据库中存一个 role字段,对应 普通用户和管理员等,然后用户登录的时候 设置session.role = ?,
然后在每个路由上加上auth (if req.session = Xxx) {//…}(就可以了
和你一样的做法,我是用的hapi框架不是express,写一个auth插件,数据库中存一个role字段,
可以配置admin,monitor, app等等细分权限,然后路由规则也是以权限名作为url开头,用户登录的时候将role信息存到
localStorage,在服务器端路由中判断该路由名字的权限是否为真。
你这种情况需要用角色权限控制,每个登录用户拥有一个角色,每个角色对应一组权限也就是可以访问的url,如果角色的权限可以动态改变就需要把角色存库来动态获取,其实也就是楼上有人说的在user中加一个role字段来控制权限
CNode 社区为国内最专业的 Node.js 开源技术社区,致力于 Node.js 的技术研究。
服务器赞助商为
,存储赞助商为
,由提供应用性能服务。
新手搭建 Node.js 服务器,推荐使用无需备案的

我要回帖

 

随机推荐