为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。

http://www.cnblogs.com/shijiaqi1066/p/3821150.html

本文使用node.js v0.10.28 + express 4.2.0

1 Express概述

Express 是一个简洁而灵活的node.js的MVC Web应用框架,提供一系列强大特性创建各种Web应用。

Express 不对 node.js 已有的特性进行二次抽象,我们只是在它之上扩展了Web应用所需的功能。

Expressd底层由Node.js的HTTP模块实现。

1.1 express 4.x 安装

express 4.x与之前的版本有了许多的变化,书里和网上的很多方法都不再适用。学习需要更多的参考官方文档。

若需要用express 3.x版本,直接使用nmp 中的@字符确定版本,指令如下:

npm install -g express-generator@3

若需要使用4.x,注意的问题在4.x版本express 已经把命令行工具分离出来。

现在全局安装只需要安装这个命令行工具就可以,指令如下:

npm install -g express-generator

1.2 创建express工程

使用express命令

express [options]

选项:

-h, --help         输出使用信息

-V, --version      输出版本号

-e, --ejs          添加ejs的支持(默认使用jade)

-H, --hogan       添加hogan.js引擎的支持

-c, --css          添加css(less 或stylus 或compass)的支持

-f, --force         强迫接受非空目录

1.2.1 创建hello-express的工程

使用命令:express hello-express ,默认创建基于jade的项目。

使用-e参数创建基于ejs的项目。使用命令:express -e hello-express

在当前目录下会创建新的目录。

目录内容如下所示:

进入到工程目录

1.2.2 安装express及依赖

使用命令:npm install

该过程会自动下载网络上的依赖包,请耐心等待命令结束。创建包后,可查看目下的package.json文件:

1.2.3 启动工程

使用命令:npm start

注意:该实例无法以 node app.js 为启动方式,而是用指令 npm start 作为启动。原因如下所述。

npm执行的时候会读取当前目录的package.json文件,这个也就是我上面那个bug出现的原因

执行npm start其实是执行package.json中的script对应的对象中的start属性所对应的命令行。

也就是执行bin/www文件,该文件无后缀名。使用文本工具打开,可以看到其中的脚本。npm start命令,就是执行的该脚本程序。

express默认端口为3000。浏览器访问 http://127.0.0.1:3000/ 。显示页面Welcome to Express,即安装成功。

1.3 目录解释

如果浏览这个子目录,就会发现express自动生成了以下的子目录和文件。

  • node_modules子目录:用于安装本地模块。
  • public子目录:用于存放用户可以下载到的文件,比如图片、脚本、样式表等。
  • routes子目录:用于存放路由文件。
  • views子目录:用于存放网页的模板。
  • app.js文件:应用程序的启动脚本。
  • package.json文件:项目的配置文件。

当对express工程目录和package.json文件熟悉后,可以手动创建工程,而不用依赖express命令。

1.4 解析express命令生成工程的代码

bin/www

#!/usr/bin/env node

var debug = require('debug')('hello-express');
var app = require('../app'); //引入app模块 app.set('port', process.env.PORT || 3000); //设置’port’ var server = app.listen(app.get('port'), function() { //获取’port’,并监听。
debug('Express server listening on port ' + server.address().port); });

app.js

var express = require('express');    //引入express
var path = require('path'); //引入path
var favicon = require('static-favicon'); //引入static-favicon
var logger = require('morgan'); //引入morgan
var cookieParser = require('cookie-parser'); //引入cookie-parser
var bodyParser = require('body-parser'); //引入body-parser var routes = require('./routes/index'); //引入路由index
var users = require('./routes/users'); //引入路由users var app = express(); //创建一个app // 设置视图引擎。
app.set('views', path.join(__dirname, 'views')); //设置视图文件所在位置。
app.set('view engine', 'ejs'); //设置视图引擎。 app.use(favicon());
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded());
app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); //指定静态文件所在位置 /* 请求时,服务器端就到public目录寻找这个文件。比如,浏览器发出如下的样式表请求: <link href="/bootstrap/css/bootstrap.css" rel="stylesheet"> 服务器端就到public/bootstrap/css/目录中寻找bootstrap.css文件。 */ app.use('/', routes); //对’/’设置路由。
app.use('/users', users); //对’/user’设置路由。 //捕获404并对跳转错误进行处理。
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
}); // 开发环境错误处理。
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', { //渲染error.ejs。
message: err.message,
error: err
});
});
} // 生产环境错误处理。
// 没有堆栈跟踪泄露给用户。
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
}); module.exports = app; //将app设为模块。

views/index.ejs

<!DOCTYPE html>
<html>
<head>
<title><%= title %></title>
<link rel='stylesheet' href='/stylesheets/style.css' /> <!--由于已经设置了静态文件位置,服务器会自动在public目录中寻找。-->
</head>
<body>
<h1><%= title %></h1>
<p>Welcome to <%= title %></p>
</body>
</html>

views/error.ejs

<h1><%= message %></h1>
<h2><%= error.status %></h2>
<pre><%= error.stack %></pre>

routes/index.js

var express = require('express');
var router = express.Router(); //获取路由对象。 /* GET home page. */
router.get('/', function(req, res) {
res.render('index', { title: 'Express' }); //页面渲染index.ejs。
}); module.exports = router; //设置为模块。

routes/users.js

var express = require('express');
var router = express.Router(); //获取路由对象。 /* GET users listing. */
router.get('/', function(req, res) {
res.send('respond with a resource'); //respones直接返回字符串。
}); module.exports = router; //将本路由设置为模块。

2 Express基本组件

2.1 Express的中间件

Express中的中间件(middleware)类似于JavaEE中拦截器的概念。

Express中的中间件由函数表示:

function uselessMiddleware(req, res, next) {
next();
}

每个中间件都可以对HTTP请求(request对象)做出回应。调用next方法会将request对象再传给下一个中间件。next方法如果带有参数,则代表抛出一个错误,参数为错误文本。

function uselessMiddleware(req, res, next) {
next('出错了!');
}

2.2 user()方法

user方法用于将路径与中间件函数或路由对象绑定起来。默认路径为”/”。

app.use([path], function)

var express = require('express');

var app = express();

// simple logger
app.use(function(req, res, next){
console.log('%s %s', req.method, req.url);
next();
}); // respond
app.use(function(req, res, next){
res.send('Hello World');
}); app.listen(3000);

2.3 静态资源

静态资源的获取是use()函数的典型应用。express.static()方法为静态资源指定目录。use()方法用于绑定拦截http请求,若请求的静态资源存在,则返回静态资源文件。

例:js、css、图片分别位于工程路径的public目录中。

// GET /static/javascripts/jquery.js
// GET /static/style.css
// GET /static/favicon.ico
app.use(express.static(__dirname + '/public'));

注意:

对不同url使用use()函数,各use()函数顺序,先拦截到http请求的中间件函数会先被执行。而且,use()方法与路由方法的顺序也需要注意。

一般的,use()方法位于路由方法之前。

例:当请求"GET /javascripts/jquery.js" 时,会先检查 "./public/javascripts/jquery.js",若不存在,随后的中间件会检查 "./files/javascripts/jquery.js"。

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

2.4 异常处理

定义错误处理的中间件跟定义普通的中间件没有什么区别,仅仅是参数必须定义为4个,定义如下 (err, req, res, next)

app.use(function(err, req, res, next){
console.error(err.stack);
res.send(500, 'Something broke!');
});

2.5 请求路由

2.5.1 路由方法

app.VERB(url, callback(req, res))

app.VERB(url, callback1(req, res),callback2(req, res),......,callbackn(req, res))

app.VERB() 方法为Express提供路由方法,VERB 是指某一个HTTP 动作,比如,app.post()。

app.VERB() 方法可以提供多个callbacks,多个callbacks会被平等对待,它们的行为跟中间件类似,不同的是,若某一个callback执行了next('route'),此后的callback就被忽略。这种情形会应用在当满足一个路由前缀,但是不需要处理这个路由,于是把它向后传递。

2.5.2 Router 路由

Express 4.x使用Router组件对URL进行响应处理。在Express 4.x 应该尽量多使用 express.Router 来代替app.VERB方式的路由。

express.Router使得整个控制器变成了一个不依赖于任何外部实例的独立模块,更有利于模块的拆分,同时对于测试也更加友好。

express.Router可以认为是一个微型的只用来处理中间件与控制器的app,它拥有和 app 类似的方法,例如 get、post、all、use 等等。

app.js

app.use(require('./controllers/book'));

controllers/book.js

var router = require('express').Rouer(); // 新建一个 router

var A = require('../middlewares/A');
var B = require('../middlewares/B');
var C = require('../middlewares/C'); // 在 router 上装备控制器与中间件
router.get('/books', A, B, C, function (req, res) {
var retA = req.A; // 中间件 A 的输出结果
var retB = req.B; // 中间件 B 的输出结果
var retC = req.C; // 中间件 C 的输出结果
// ... 其余程序逻辑
}); // ...
// 返回 router 供 app 使用
module.exports = router;

通过 express.Router,控制器与中间件的代码紧密的联系在一起,并且避免了传递 app 的潜在风险。同时,一个 router 就是一个完整的功能模块,不需要任何装配就可以执行。这一点对于单元测试来说非常简单。

2.5.3 中间件重用

express.Router 可以认为是一个迷你的 app,它拥有一个独立的中间件队列。这个特性可以用来共享一些常用的中间件,例如:

例:parseBook方法是个中间件方法。

var bookRouter = express.Router();

app.use('/books', bookRouter);

//路由指定中间件
bookRouter.use(parseBook); //如下三个控制器都会经过 parseBook 中间件。
bookRouter.get('/books/:bookId', viewBook);
bookRouter.get('/books/:bookId/edit', editBook);
bookRouter.get('/books/:bookId/move', moveBook); app.get('/other_link', otherController); // 不会经过 parseBook 中间件。

例:Restful的Router。

var bookRouter = express.Router();
bookRouter
.route('/books/:bookId?')
.get(function (req, res) {
// ...
})
.put(function (req, res) {
// ...
})
.post(function (req, res) {
// ...
})
.delete(function (req, res) {
// ...
})

app.route

假定app是Express的实例对象,Express 4.0为该对象提供了一个route属性。app.route实际上是express.Router()的缩写形式,直接挂载到根路径。

app.route('/login')
.get(function(req, res) {
res.send('this is the login form');
})
.post(function(req, res) {
console.log('processing');
res.send('processing the login form!');
});

2.6 request对象

使用req.query解析http查询字符串

// GET /search?q=tobi+ferret
req.query.q
// => "tobi ferret" // GET /shoes?order=desc&shoe[color]=blue&shoe[type]=converse
req.query.order
// => "desc" req.query.shoe.color
// => "blue" req.query.shoe.type
// => "converse"

使用req.params获取url中的参数

app.get('/blog/:year/:month/:day/:title', function (req, res) {
var fileName = './blogs/' +
req.params.year + '-' +
req.params.month + '-' +
req.params.day + '-' +
req.params.title + '.md';
fs.readFile(fileName, 'utf-8', function (err, data) {
if (err) {
res.send(err);
}
res.send(data);
});
});

获取请求中参数的通用方法

req.param(name)

// ?name=tobi
req.param('name')
// => "tobi" // POST name=tobi
req.param('name')
// => "tobi" // /user/tobi for /user/:name
req.param('name')
// => "tobi"

request.ip

request.ip属性用于获得HTTP请求的IP地址。

request.files

request.files用于获取上传的文件。

2.7 response对象

response.redirect方法

response.redirect方法用于网址的重定向。

response.redirect("/hello/anime");
response.redirect("http://www.example.com");
response.redirect(301, "http://www.example.com");

response.sendFile方法

response.sendFile方法用于发送文件。

response.sendFile("/path/to/anime.mp4");

response.render方法

response.render方法用于渲染网页模板。

app.get("/", function(request, response) {
response.render("index", { message: "Hello World" }); //将message变量传入index模板,渲染成HTML网页。
});

2.8 使用EJS模板

EJS是一个JavaScript模板库,用来从JSON数据中生成HTML字符串。EJS的优点是将会带给你明确、维护性良好的HTML代码结构。EJS模板以”.ejs”为后缀。

2.8.1 基本应用

数据

{
title: 'Cleaning Supplies',
supplies: ['mop', 'broom', 'duster']
}

模板

<h1><%= title %></h1>
<ul>
<% for(var i=0; i<supplies.length; i++) {%>
<li><%= supplies[i] %></li>
<% } %>
</ul>

用数据渲染模板,WEB的显示结果:

2.8.2 Include功能

EJS提供了模版包含(include)的功能,可以include不同的页面部件,组合在一起。

其语法为:<% include foot.ejs %>

2.8.3 其他

EJS实际可以不依赖Express而独立使用的。甚至在浏览器中也有很好的应用。

3 Express所需要的工具组件

Express 4.x 的版本做了很多改进,将很多功能分离出去,以第三方组件的形式为Express提供了更多的功能。同时Express也会有更好的扩展性。

3.1 body-parser

body-parser是Node.js的body解析中间件。用于解析HTTP报文body部分的数据。

body-parser无法处理multipart的body,对于multipart,可能需要使用如下模块:

· busboyconnect-busboy

· multipartyconnect-multiparty

· formidable

· multer

其他body解析器:

· body

· co-body

API示例

var express    = require('express')
var bodyParser = require('body-parser') var app = express()
// 解析application/x-www-form-urlencoded
app.use(bodyParser.urlencoded())
// 解析application/json
app.use(bodyParser.json()) // 解析application/vnd.api+json 作为json
app.use(bodyParser.json({ type: 'application/vnd.api+json' })) app.use(function (req, res, next) {
console.log(req.body) // populated!
next()
})

bodyParser.json(options)

返回一个解析json的中间件。该解析器可以接受Unicode编码的请求体,可以作自动解压缩gzip,或解码。

选项:

  • strict - 仅解析对象和数组。(default: true)
  • inflate - 设置是否解压被压缩的body (default: true)
  • limit - request的body的最大长度。 (default: <100kb>)
  • reviver - 传递给JSON.parse()
  • type - 解析的类型。(default: json)
  • verify - 判定body内容的函数。

type参数将直接传递给 type-is 库。该值可以是一个扩展名(如:json),一个mime类型(如:application/json),或者一个带通配符的mime(如:*/json)

若提供verify 参数,其函数形式为verify(req, res, buf, encoding),buf是Buffer类型,是请求体。encoding 是请求的编码。解析会被抛出的错误而中止。

reviver 参数会被直接传递给 JSON.parse方法获取其第二个参数。可以在MDN 的文档中找到更多相关资料。

bodyParser.raw(options)

返回的中间件,中间件将body作为Buffer。该解析器可以作自动解压缩gzip或者解码。

选项:

  • inflate - 同bodyParser.json (default: true)
  • limit - 同bodyParser.json (default: <100kb>)
  • type - 同bodyParser.json (default: application/octet-stream)
  • verify - 同bodyParser.json

type参数将直接传递给 type-is 库。该值可以是一个扩展名(如:bin),一个mime类型(如:application/octet-stream),或者一个带通配符的mime(如:application/*)

bodyParser.text(options)

返回的中间件,中间件将body作为字符串。该解析器可以作自动解压缩gzip或者解码。

选项:

  • defaultCharset - 若没有指定content-type,该值为默认字符集。 (default: utf-8)
  • inflate - 同bodyParser.json。 (default: true)
  • limit - 同bodyParser.json。 (default: <100kb>)
  • type - 同bodyParser.json。 (default: text/plain)
  • verify - 同bodyParser.json。

type参数将直接传递给 type-is 库。该值可以是一个扩展名(如:txt),一个mime类型(如:text/plain),或者一个带通配符的mime(如:text/*)

bodyParser.urlencoded(options)

返回一个拥有解析urlencoded 请求体的中间件。该解析器可以接受Unicode编码的请求体,该可以作自动解压缩gzip,或解码。

选项:

  • extended - 使用qs模块解析扩展的语法。(default: true)
  • inflate - 同bodyParser.json。  (default: true)
  • limit - 同bodyParser.json。  (default: <100kb>)
  • type - 同bodyParser.json。 (default: urlencoded)
  • verify - 同bodyParser.json。

extended 参数允许选择解析urlencoded 数据的库,当为false时,使用querystring 库解析,当为true时,使用qs库解析。“扩展”的语法允许富对象和数组编码为urlencoded 格式,允许类JSON表达式。更多信息请参考qs库

type参数将直接传递给 type-is 库。该值可以是一个扩展名(如:urlencoded),一个mime类型(如:application/x-www-form-urlencoded),或者一个带通配符的mime(如: */x-www-form-urlencoded)

req.body

HTTP中报文体的对象。

例:

var express = require('express');

var app = express();

app.use(express.bodyParser());

app.all('/', function(req, res){
res.send(req.body.title + req.body.text);
}); app.listen(3000);

3.2 cookie-parser

cookieParser中间件,用于分析和处理req.cookies的cookie数据。

3.3 express-session

express-session是一个为Express提供的 session中间件。

var express = require('express')
var session = require('express-session')
var app = express() app.use(session({secret: 'keyboard cat'}))

session(options)

为session设置存储选项。session ID存储于cookie,其他数据不会被存储在cookie中。

  • name - cookie的名称(默认: 'connect.sid')
  • store - session的存储实例。
  • secret - session cookie通过secret 加密。
  • cookie - session相关cookie的设置项。(默认: { path: '/', httpOnly: true, secure: false, maxAge: null })
  • genid - session ID的生成函数。 (默认: 使用uid2库。)
  • rolling - 强制对每个response的cookie设置过期日期。(默认:false)
  • resave - 强制session为被保存的。(默认:true)
  • proxy - 信任反向代理,当时也secure cookies时候,当该项为true,则"x-forwarded-proto"报文头将会被使用。当设置为false时,所有的报文头都会被忽略。若不设置,则使用express的"trust proxy"设置。(默认:undefined)
  • saveUninitialized - 强制session以"uninitialized"被保存到仓库。会话是未初始化的时不能被修改。这对实现登录会话是非常有用的。(默认:true)
  • unset - 通过该选项,删除req.session或将其设为null后,设置req.session的结局。若为”keep”,则session将会在仓库中维持着,但无法被修改;若为”destory”则将销毁仓库中的session。(默认:'keep')

options.genid

对新session生成session ID。提供一个函数。函数返回一个字符串作为session ID。函数有一个req参数,在生成ID时,可以使用一些值附加到req上。

注意:session ID需要唯一。

例:

app.use(session({
genid: function(req) {
return genuuid(); // use UUIDs for session IDs
},
secret: 'keyboard cat'
}))

Cookie选项

请注意 secure: true 是一个被推荐的选项。然而,这需要https的支持。HTTPS需要安全的Cookie。如果secure 被设置了,若使用HTTP访问网站程序时,则cookie将不会被设置。如果你的node.js在代理之后,且使用了 secure: true ,被需要设置,则需要在express中设置"trust proxy" 。

var app = express()

app.set('trust proxy', 1) // trust first proxy
app.use(session({
secret: 'keyboard cat'
, cookie: { secure: true }
}))

在生产环境下,使用安全cookie。可以为了开发测试,如下是一个的设置基于NODE_ENV的例子:

var app = express()

var sess = {
secret: 'keyboard cat'
cookie: {}
} if (app.get('env') === 'production') {
app.set('trust proxy', 1) // trust first proxy
sess.cookie.secure = true // serve secure cookies
} app.use(session(sess))

cookie.maxAge默认是null的,即expires没有配置,所以cookie用于浏览器的会话cookie。当时用户关闭浏览器,会话cookie就会被移除。

req.session

存储或访问session数据。

示例:

app.use(session({ secret: 'keyboard cat', cookie: { maxAge: 60000 }}))
app.use(function(req, res, next) {
var sess = req.session
if (sess.views) {
sess.views++
res.setHeader('Content-Type', 'text/html')
res.write('<p>views: ' + sess.views + '</p>')
res.write('<p>expires in: ' + (sess.cookie.maxAge / 1000) + 's</p>')
res.end()
} else {
sess.views = 1
res.end('welcome to the session demo. refresh!')
}
})

session.regenerate()

调用该方法重新生成session,一旦完成一个SID,Session实例将会在req.session中被初始化。

req.session.regenerate(function(err) {
// 此处将使用一个新的session。
})

session.destroy()

销毁session,移除req.session,将会重新生成下一个request。

req.session.destroy(function(err) {
// 此处无法使用session
})

session.reload()

重新加载session数据。

req.session.reload(function(err) {
// session升级
})

session.save()

req.session.save(function(err) {
// session被保存
})

session.touch()

更新maxAge属性。该方法不需要调用,session中间件会自动做这件事情。

req.session.cookie

每个session必须有一个唯一的cookie对象对应。

  • req.session.cookie.expires  用于cookie的过期设置。若req.session.cookie.expires设置为false,则使得cookie仅保持用户代理。
  • req.session.cookie.maxAge  为session.cookie的剩余时间,单位为毫秒。

例:设置并查看cookie.maxAge的时间

var hour = 3600000
req.session.cookie.expires = new Date(Date.now() + hour)
req.session.cookie.maxAge = hour

30秒之后,req.session.cookie.maxAge返回剩余时间。

req.session.cookie.maxAge // => 30000

Session仓库的实现

每个session仓库必须实现如下方法:

  • .get(sid, callback)
  • .set(sid, session, callback)
  • .destroy(sid, callback)

推荐实现也实现如下方法:

  • .length(callback)
  • .clear(callback)

例:以下是一个redis的实现。

https://github.com/visionmedia/connect-redis

Express官方资料:

http://expressjs.com/

https://www.npmjs.org/package/express

https://github.com/visionmedia/expressjs.com

https://github.com/visionmedia/express#quick-start

body-parser相关参考资料:

https://github.com/expressjs/body-parser

https://www.npmjs.org/package/body-parser

cookie-parser相关参考资料:

https://github.com/expressjs/cookie-parser

https://www.npmjs.org/package/cookie-parser

express-session相关参考资料:

https://github.com/expressjs/session

https://www.npmjs.org/package/express-session

关于expressjs更多的组件请在如下地址搜索:

https://github.com/expressjs

https://www.npmjs.org/

感谢如下博客作者为我们提供的学习资料:

http://javascript.ruanyifeng.com/nodejs/express.html

http://www.cnblogs.com/moonpanda/p/3669735.html

http://blog.segmentfault.com/nark/1190000000488358

http://lostjs.com/2014/04/24/upgrade-express-4/

https://github.com/visionmedia/express/wiki/Migrating-from-3.x-to-4.x

http://www.cnblogs.com/yuanzm/p/3770986.html

http://my.oschina.net/tangdu/blog/282207

http://www.cnblogs.com/ahl5esoft/p/3769781.html

http://www.90it.net/topic/web/node

为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处。LaplaceDemon/SJQ。

http://www.cnblogs.com/shijiaqi1066/p/3821150.html

Express 4.x Node.js的Web框架的更多相关文章

  1. Express 4.x Node.js的Web框架----《转载》

    本文使用node.js v0.10.28 + express 4.2.0 1 Express概述 Express 是一个简洁而灵活的node.js的MVC Web应用框架,提供一系列强大特性创建各种W ...

  2. koa : Express出品的下一代基于Node.js的web框架

    https://www.liaoxuefeng.com/wiki/001434446689867b27157e896e74d51a89c25cc8b43bdb3000/001434501579966a ...

  3. 7个Node.js的Web框架

    NodeJS也就是Node,是众所周知的使用javascript构建Web应用框架,它启动一个服务器非常简单,如下: var http = require('http'); http.createSe ...

  4. 基于node.js的web框架express

    1.安装node.js方法: window :https://nodejs.org/en/ linux:http://www.runoob.com/nodejs/nodejs-install-setu ...

  5. 搭建Node.js的Web框架egg.js

    1 egg.js的Request处理流程: 2. 使用nodejs下载egg.js框架 (1)现在nodejs中全局安装egg-init 即在nodejs安装根目录下执行  : d:cd nodejs ...

  6. node.js之web开发 koa入门

    用Node.js开发Web服务器端,有几个显著的优势: 速度快,非常快!这得益于Node.js天生是异步的. 常见的Web框架包括:Express,Sails.js,koa,Meteor,DerbyJ ...

  7. 快速使用node.js进行web开发

    首先关于node.js的学习,这里推荐一本比较好的教程,nodejs web开发指南,该书通俗易懂地将node.js语言特性讲解完之后,又从一个项目角度带领读者使用node.js学习web开发.相信这 ...

  8. node.js中的框架

    node.js中的框架 载自: http://nodeframework.com/ MVC frameworks Sinatra-like These frameworks offer rich co ...

  9. Node.js 搭建Web

    Express Express 是整个 Node.js 之中最为常见的一个框架(开发包),可以帮助我们快速构建一个WEB项目.(http://expressjs.com) 1.在 F 盘新建 node ...

随机推荐

  1. MANACHER---求最长回文串

    求最长回文串,如果是暴力的方法的话,会枚举每个字符为中心,然后向两边检测求出最长的回文串,时间复杂度在最坏的情况下就是0(n^2),为什么时间复杂度会这么高,因为对于每一个作为中心的字符的检测是独立的 ...

  2. [iOS微博项目 - 1.5] - NavigationBar标题按钮

    A.NavigationBar标题按钮 1.需求 在“首页”的导航栏中部设置一个“首页”文字+箭头按钮 统一设置样式 根据实际文本长度调整宽度 消除系统自带的点击高亮效果 点击按钮,箭头上下颠倒 gi ...

  3. UVa 1252 Twenty Questions (状压DP+记忆化搜索)

    题意:有n件物品,每件物品有m个特征,可以对特征进行询问,询问的结果是得知某个物体是否含有该特征,要把所有的物品区分出来(n个物品的特征都互不相同), 最小需要多少次询问? 析:我们假设心中想的那个物 ...

  4. Chapter 8. Classes

    8.1. Class Declarations 8.1.1. Class Modifiers 8.1.1.1. abstract Classes 8.1.1.2. final Classes 8.1. ...

  5. SQL Select的执行顺序

    1.FROM 2.ON 3.JOIN 4.WHERE 5.GROUP BY 6.WITH CUBE or WITH ROLLUP 7.HAVING 8.SELECT 9.DISTINCT 10.ORD ...

  6. ThinkPHP3.1.3的单字母函数汇总

    A函数: 用于实例化Action 格式:[项目://][分组/]模块 /** * A函数用于实例化Action 格式:[项目://][分组/]模块 * @param string $name Acti ...

  7. HDU 4121 Xiangqi 模拟题

    Xiangqi Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=4121 ...

  8. goldengate的HANDLECOLLISIONS参数

    HANDLECOLLISIONS 是一个 replicat 进程参数,主要在 initial load 中使用. 在 replicat 进程中使用该参数时,即使目标数据库环境中存在数据完整性问题(如 ...

  9. OpenStack Magnum 项目简单介绍

    背景 Magnum 项目是 2014 年 11 月增加 OpenStack 的年轻项目,由 Rackspace主导发起,其定位是提供容器即服务(Container as a Service)的 API ...

  10. Particle designer 粒子工具中属性对应功能的简单介绍

    粒子配置 Max Particles 粒子的数量  一般而言,我们的目标是用最少的粒子创造出所需的效果.单个粒子的大小对游戏运行效率也有很大的影响——单个粒子越小,性能越高. Lifespan 生命周 ...