Express
一个node框架
安装为
npm inatslll --save express
使用为优先创造一个node项目
npm init
entry point: (index.js)
npm install express --save
Express 脚手架(程序生成器)
npm install express-generator -g
// 创建项目myapp
express --view=pug myapp
// 启动
npm install
SET DEBUG=myapp:* & npm start
Express 路由
请求方式
app.METHOD(PATH, HANDLER)
app是一个实例express。
METHOD是一个HTTP请求方法,小写。
PATH 是服务器上的路径。
HANDLER 是路由匹配时执行的功能。
METHOD可以使用的:(请求方式)
checkout
copy
delete
get
head
lock
merge
mkactivity
mkcol
move
m-search
notify
options
patch
post
purge
put
report
search
subscribe
trace
unlock
unsubscribe
var express = require('express');
var app = express();
// 路由请求事例
app.get('/', function (req, res) {
res.send('Hello World!')
})
app.post('/', function (req, res) {
res.send('Got a POST request')
})
app.put('/user', function (req, res) {
res.send('Got a PUT request at /user')
})
app.delete('/user', function (req, res) {
res.send('Got a DELETE request at /user')
})
app.all('/user', function (req, res) {
res.send('Got a DELETE request at /user')
})
app.param([name],callback)
//为确定添加参数内容
app.param('id', function (req, res, next, id) {
console.log('CALLED ONLY ONCE');
next();
});
app.get('/user/:id', function (req, res, next) {
console.log('although this matches');
next();
});
app.get('/user/:id', function (req, res) {
console.log('and this matches too');
res.end();
});
//在GET /user/42,输出
CALLED ONLY ONCE
although this matches
and this matches too
// 使用两个参数
app.param(['id', 'page'], function (req, res, next, value) {
console.log('CALLED ONLY ONCE with', value);
next();
});
app.get('/user/:id/:page', function (req, res, next) {
console.log('although this matches');
next();
});
app.get('/user/:id/:page', function (req, res) {
console.log('and this matches too');
res.end();
});
// 使用/user/42/3,输出
CALLED ONLY ONCE with 42
CALLED ONLY ONCE with 3
although this matches
and this matches too
路由拦截: /只有工作号为1337可以进入
var express = require('express');
var app = express();
// customizing the behavior of app.param()
app.param(function(param, option) {
return function (req, res, next, val) {
if (val == option) {
next();
}
else {
next('route');
}
}
});
// using the customized app.param()
app.param('id', 1337);
// route to trigger the capture
app.get('/user/:id', function (req, res) {
res.send('OK');
});
app.listen(3000, function () {
console.log('Ready');
});
检测id类型
app.param(function(param, validator) {
return function (req, res, next, val) {
if (validator(val)) {
next();
}
else {
next('route');
}
}
});
app.param('id', function (candidate) {
return !isNaN(parseFloat(candidate)) && isFinite(candidate);
});
可以使用正则来检测路由
//captures '1-a_6' but not '543-azser-sder'
router.get('/[0-9]+-[[\\w]]*', function);
//captures '1-a_6' and '543-az(ser"-sder' but not '5-a s'
router.get('/[0-9]+-[[\\S]]*', function);
//captures all (equivalent to '.*')
router.get('[[\\s\\S]]*', function);
//检测 ‘/user-[\\s\\S]+/’
router.get('/user-[\\s\\S]+/', function);
处理中间件错误
app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});
匹配路径类型
app.use('/abcd', function (req, res, next) {
next();
})
以`/ abcd`和`/ abd`开头的路径: '/abc?d';
以`/ abcd`,`/ abbcd`,`/ abbbbbcd`开头的路径: '/ab+cd'
以`/ abcd`,`/ abxcd`,`/ abFOOcd`,`/ abbArcd`开头的路径: '/ab\*cd'
以`/ ad`和`/ abcd`开头的路径: '/a(bc)?d'
// 正则判断
以`/ abc`和`/ xyz`开头的路径: /\/abc|\/xyz/
// 排列判断
以`/ abcd`,`/ xyza`,`/ lmn`和`/ pqr`开头的路径: ['/abcd', '/xyza', /\/lmn|\/pqr/]
req–函数的参数
req.app
req.baseUrl --获取路由取首
当发出请求时/greet/jp,req.baseUrl是“/ greet”。当发出请求时/hello/jp,req.baseUrl是“/ hello”
####req.body–提交的键值对数据
使用方法有多种
一,文档提供使用body-parser解决
var app = require('express')();
var bodyParser = require('body-parser');
var multer = require('multer'); // v1.0.5
var upload = multer(); // for parsing multipart/form-data
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.post('/profile', upload.array(), function (req, res, next) {
console.log(req.body);
res.json(req.body);
});
第二种,不使用
var express = require('express');
var app = express();
var multer = require('multer'); // v1.0.5
var upload = multer(); // for parsing multipart/form-data
app.use(express.json()); // for parsing application/json
app.use(express.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded
app.post('/profile', upload.array(), function (req, res, next) {
console.log(req.body);
res.json(req.body);
});
####req.cookie
使用cookie-parser中间件时,此属性是包含请求发送的cookie的对象。如果请求不包含cookie,则默认为{}
// Cookie: name=tj
req.cookies.name
// => "tj"
req.ip
包含请求的远程IP地址
req.method --请求方式
包含对应于该请求的HTTP方法的字符串: GET
,POST
,PUT
,等
####req.originalUrl --原始请求URL
app.use('/admin', function(req, res, next) { // GET 'http://www.example.com/admin/new'
console.log(req.originalUrl); // '/admin/new'
console.log(req.baseUrl); // '/admin'
console.log(req.path); // '/new'
next();
});
req.params --此属性是一个对象 传入值
如果您有路线/user/:name,则“name”属性可用作req.params.name。该对象默认为{}
// GET /user/tj
req.params.name
// => "tj"
// GET /file/javascripts/jquery.js
req.params[0]
// => "javascripts/jquery.js"
####req.path --包含请求URL的路径部分
req.query–路由中每个查询字符串参数的属性(?q=as)
// 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.route–当前匹配的路由,一个字符串
// app
app.get('/user/:id?', function userIdHandler(req, res) {
console.log(req.route);
res.send('GET');
});
// 输出
{ path: '/user/:id?',
stack:
[ { handle: [Function: userIdHandler],
name: 'userIdHandler',
params: undefined,
path: undefined,
keys: [],
regexp: /^\/?$/i,
method: 'get' } ],
methods: { get: true } }
####req.secure – 是否建立了TLS连接
'https' == req.protocol;
####req.xhr–判断是否是如果请求的X-Requested-With
头字段是“XMLHttpRequest”,jquery请求
req.xhr
// => true
req.accepts(类型)
根据请求的Accept
HTTP头字段检查指定的内容类型是否可接受。该方法返回最佳匹配,或者如果没有指定的内容类型可接受,则返回false
(在这种情况下,应用程序应响应406 "Not Acceptable"
)。
该type
值可以是单个MIME类型字符串(例如“application / json”),扩展名如“json”,逗号分隔列表或数组。对于列表或数组,该方法返回最佳匹配(如果有)。
// Accept: text/html
req.accepts('html');
// => "html"
// Accept: text/*, application/json
req.accepts('html');
// => "html"
req.accepts('text/html');
// => "text/html"
req.accepts(['json', 'text']);
// => "json"
req.accepts('application/json');
// => "application/json"
// Accept: text/*, application/json
req.accepts('image/png');
req.accepts('png');
// => undefined
// Accept: text/*;q=.5, application/json
req.accepts(['html', 'json']);
// => "json"
req.acceptsCharsets(charset [,…])
根据请求的Accept-Charset
HTTP头字段返回指定字符集的第一个接受的字符集。如果未接受任何指定的字符集,则返回false
。
req.acceptsEncodings(encoding [,…])
根据请求的Accept-Encoding
HTTP头字段,返回指定编码的第一个接受编码。如果未接受任何指定的编码,则返回false
。
req.acceptsLanguages(lang [,…])
根据请求的Accept-Language
HTTP头字段返回指定语言的第一个接受语言。如果未接受任何指定的语言,则返回false
。
req.get() --返回指定的HTTP请求标头字段(不区分大小写的匹配)
req.get('Content-Type');
// => "text/plain"
req.get('content-type');
// => "text/plain"
req.get('Something');
// => undefined
####req.is(类型)
如果传入请求的“Content-Type”HTTP标头字段与type
参数指定的MIME类型匹配,则返回匹配的内容类型。如果请求没有正文,则返回null
。false
否则返回。
// With Content-Type: text/html; charset=utf-8
req.is('html'); // => 'html'
req.is('text/html'); // => 'text/html'
req.is('text/*'); // => 'text/*'
// When Content-Type is application/json
req.is('json'); // => 'json'
req.is('application/json'); // => 'application/json'
req.is('application/*'); // => 'application/*'
req.is('html');
// => false
req.range(size [,options])
Range
头解析器。
该size
参数是资源的最大尺寸。
所述options
参数是一个对象,可以具有以下性质。
combine :指定是否应组合重叠和相邻范围,默认为false
。何时true
,范围将被组合并返回,就好像它们在标题中指定了那样
将返回范围数组或指示错误解析的负数。
-
-2
表示格式错误的标题字符串 -
-1
表示不可满足的范围// parse header from request var range = req.range(1000) // the type of the range if (range.type === 'bytes') { // the ranges range.forEach(function (r) { // do something with r.start and r.end }) }
res–函数的参数
res.headersSent —布尔属性,指示应用程序是否为响应发送了HTTP标头
app.get('/', function (req, res) {
console.log(res.headersSent); // false
res.send('OK');
console.log(res.headersSent); // true
});
####res.append(field [,value])追加请求头
res.append('Link', ['<http://localhost/>', '<http://localhost:3000/>']);
res.append('Set-Cookie', 'foo=bar; Path=/; HttpOnly');
res.append('Warning', '199 Miscellaneous warning');
res.cookie(name,值)–json格式
属性 | 类型 | 描述 |
---|---|---|
domain | 串 | Cookie的域名。默认为应用程序的域名。 |
encode | 功能 | 用于cookie值编码的同步函数。默认为encodeURIComponent 。 |
expires | 日期 | GMT中cookie的到期日。如果未指定或设置为0,则创建会话cookie。 |
httpOnly | 布尔 | 标记cookie只能由Web服务器访问。 |
maxAge | 数 | 方便的选项,用于设置相对于当前时间的到期时间(以毫秒为单位)。 |
path | 串 | Cookie的路径。默认为“/”。 |
secure | 布尔 | 将cookie标记为仅与HTTPS一起使用。 |
signed | 布尔 | 指示cookie是否应该签名。 |
sameSite | 布尔值或字符串 | “SameSite” Set-Cookie属性的值。更多信息,请访问https://tools.ietf.org/html/draft-ietf-httpbis-cookie-same-site-00#section-4.1.1。 |
####res.download(path [,filename][,options] [,fn])–下载
将文件path
作为“附件” 传输。通常,浏览器会提示用户下载。默认情况下,Content-Disposition
标题“filename =”参数是path
(这通常出现在浏览器对话框中)。使用filename
参数覆盖此默认值。
发生错误或传输完成时,该方法将调用可选的回调函数fn
。此方法使用res.sendFile()来传输文件。
可选options
参数传递给基础res.sendFile() 调用,并采用完全相同的参数
res.download('/report-12345.pdf');
res.download('/report-12345.pdf', 'report.pdf');
res.download('/report-12345.pdf', 'report.pdf', function(err){
if (err) {
// Handle error, but keep in mind the response may be partially-sent
// so check res.headersSent
} else {
// decrement a download credit, etc.
}
});
####res.end()–结束响应
用于在没有任何数据的情况下快速结束响应。如果需要响应数据,请使用res.send()和res.json()等方法。
res.end();
res.status(404).end();
res.format(对象)
Accept
对请求对象上的HTTP标头执行内容协商(如果存在)。它使用req.accepts()根据质量值排序的可接受类型为请求选择处理程序。如果未指定标头,则调用第一个回调。如果未找到匹配项,则服务器将以406“Not Acceptable”响应,或调用default
回调。
在Content-Type
当选择一个回调响应首部设置。但是,您可以使用诸如res.set()
或之类的方法在回调中更改此值res.type()
。
{ "message": "hey" }
当Accept
header字段设置为“application / json”或“* / json” 时,以下示例将响应(但如果它是“* / *”,则响应将为“hey”)。
res.format({
'text/plain': function(){
res.send('hey');
},
'text/html': function(){
res.send('<p>hey</p>');
},
'application/json': function(){
res.send({ message: 'hey' });
},
'default': function() {
// log the request and respond with 406
res.status(406).send('Not Acceptable');
}
});
除了规范化的MIME类型之外,您还可以使用映射到这些类型的扩展名来实现稍微冗长的实现
res.format({
text: function(){
res.send('hey');
},
html: function(){
res.send('<p>hey</p>');
},
json: function(){
res.send({ message: 'hey' });
}
});
res.get(请求头)-- 获取请求头
res.get('Content-Type');
// => "text/plain"
res.json(对象)–发送JSON数据
res.status(500) --设置状态码
res.json(null);
res.json({ user: 'tobi' });
res.status(500).json({ error: 'message' });
res.jsonp(对象) --jsonp回调
res.jsonp(null);
// => callback(null)
res.jsonp({ user: 'tobi' });
// => callback({ "user": "tobi" })
res.status(500).jsonp({ error: 'message' });
// => callback({ "error": "message" })
默认情况下,JSONP回调名称很简单callback
。使用jsonp回调名称设置覆盖它 。
以下是使用相同代码的JSONP响应的一些示例:
// ?callback=foo
res.jsonp({ user: 'tobi' });
// => foo({ "user": "tobi" })
app.set('jsonp callback name', 'cb');
// ?cb=foo
res.status(500).jsonp({ error: 'message' });
// => foo({ "error": "message" })
####res.links(链接)–将links
提供的as作为参数的属性加入,以填充响应的 Link
HTTP头字段
res.links({
next: 'http://api.example.com/users?page=2',
last: 'http://api.example.com/users?page=5'
});
得到以下结果:
Link: <http://api.example.com/users?page=2>; rel="next",
<http://api.example.com/users?page=5>; rel="last"
####res.location(路径)
将响应Location
HTTP标头设置为指定的path
参数。
res.location('/foo/bar');
res.location('http://example.com');
res.location('back');
####res.redirect([status,] path) --重新定向
重定向到从指定的URL派生的URL path
,具有指定的status
与HTTP状态代码对应的正整数。如果未指定,则status
默认为“302”找到“。
res.redirect('/foo/bar');
res.redirect('http://example.com');
res.redirect(301, 'http://example.com');
res.redirect('../login');
res.sendStatus(的StatusCode)
将响应HTTP状态代码设置为statusCode
并将其字符串表示形式发送为响应正文。
res.sendStatus(200); // equivalent to res.status(200).send('OK')
res.sendStatus(403); // equivalent to res.status(403).send('Forbidden')
res.sendStatus(404); // equivalent to res.status(404).send('Not Found')
res.sendStatus(500); // equivalent to res.status(500).send('Internal Server Error')
如果指定了不受支持的状态代码,则HTTP状态仍设置为,statusCode
并且代码的字符串版本将作为响应正文发送。
res.sendStatus(2000); // equivalent to res.status(2000).send('2000'
res.set(field [,value]) --设置请求头
res.set('Content-Type', 'text/plain');
res.set({
'Content-Type': 'text/plain',
'Content-Length': '123',
'ETag': '12345'
})
res.type(类型)
将Content-Type
HTTP标头设置为由mime.lookup()为指定的MIME类型确定的MIME类型 type
。如果type
包含“/”字符,则将其设置Content-Type
为type
。
res.type('.html'); // => 'text/html'
res.type('html'); // => 'text/html'
res.type('json'); // => 'application/json'
res.type('application/json'); // => 'application/json'
res.type('png'); // => image/png:
多层回调
var cb0 = function (req, res, next) {
console.log('CB0')
next()
}
var cb1 = function (req, res, next) {
console.log('CB1')
next()
}
var cb2 = function (req, res) {
res.send('Hello from C!')
}
app.get('/example/c', [cb0, cb1, cb2])
独立函数和函数数组的组合可以处理路径。例如:
var cb0 = function (req, res, next) {
console.log('CB0')
next()
}
var cb1 = function (req, res, next) {
console.log('CB1')
next()
}
app.get('/example/d', [cb0, cb1], function (req, res, next) {
console.log('the response will be sent by the next function ...')
next()
}, function (req, res) {
res.send('Hello from D!')
})
Express托管静态文件
express.static(root,[option])
root参数指定为静态资产提供服务的根目录
// 通过如下代码就可以将 public 目录下的图片、CSS 文件、JavaScript 文件对外开放访问了可以开放多个
app.use(express.static('public'))
// 使用/stad来访问,例如http://localhost:3000/static/images/kitten.jpg
app.use('/stad',express.static('public'))
数据库集成
Cassandra
npm install cassandra-driver
var cassandra = require('cassandra-driver')
var client = new cassandra.Client({ contactPoints: ['localhost'] })
client.execute('select key from system.local', function (err, result) {
if (err) throw err
console.log(result.rows[0])
})
Couchbase
npm install couchbase
var couchbase = require('couchbase')
var bucket = (new couchbase.Cluster('http://localhost:8091')).openBucket('bucketName')
// add a document to a bucket
bucket.insert('document-key', { name: 'Matt', shoeSize: 13 }, function (err, result) {
if (err) {
console.log(err)
} else {
console.log(result)
}
})
// get all documents with shoe size 13
var n1ql = 'SELECT d.* FROM `bucketName` d WHERE shoeSize = $1'
var query = N1qlQuery.fromString(n1ql)
bucket.query(query, [13], function (err, result) {
if (err) {
console.log(err)
} else {
console.log(result)
}
})
CouchDB
npm install nano
var nano = require('nano')('http://localhost:5984')
nano.db.create('books')
var books = nano.db.use('books')
// Insert a book document in the books database
books.insert({ name: 'The Art of war' }, null, function (err, body) {
if (err) {
console.log(err)
} else {
console.log(body)
}
})
// Get a list of all books
books.list(function (err, body) {
if (err) {
console.log(err)
} else {
console.log(body.rows)
}
})
###LevelDB
npm install level levelup leveldown
var levelup = require('levelup')
var db = levelup('./mydb')
db.put('name', 'LevelUP', function (err) {
if (err) return console.log('Ooops!', err)
db.get('name', function (err, value) {
if (err) return console.log('Ooops!', err)
console.log('name=' + value)
})
})
MySQL
npm install mysql
var mysql = require('mysql')
var connection = mysql.createConnection({
host : 'localhost',
user : 'dbuser',
password : 's3kreee7',
database : 'my_db'
});
connection.connect()
connection.query('SELECT 1 + 1 AS solution', function (err, rows, fields) {
if (err) throw err
console.log('The solution is: ', rows[0].solution)
})
connection.end()
MongoDB
npm install mongodb
MongoDB(2.*)
var MongoClient = require('mongodb').MongoClient
MongoClient.connect('mongodb://localhost:27017/animals', function (err, db) {
if (err) throw err
db.collection('mammals').find().toArray(function (err, result) {
if (err) throw err
console.log(result)
})
})
MongoDB(3.*)
var MongoClient = require('mongodb').MongoClient
MongoClient.connect('mongodb://localhost:27017/animals', function (err, client) {
if (err) throw err
var db = client.db('animals')
db.collection('mammals').find().toArray(function (err, result) {
if (err) throw err
console.log(result)
})
})
Neo4j
npm install apoc
var apoc = require('apoc')
apoc.query('match (n) return n').exec().then(
function (response) {
console.log(response)
},
function (fail) {
console.log(fail)
}
)
Oracle
npm install oracledb
const oracledb = require('oracledb');
const config = {
user: '<your db user>', // Update me
password: '<your db password>', // Update me
connectString: 'localhost:1521/orcl' // Update me
};
async function getEmployee(empId) {
let conn;
try {
conn = await oracledb.getConnection(config);
const result = await conn.execute(
'select * from employees where employee_id = :id',
[empId]
);
console.log(result.rows[0]);
} catch (err) {
console.log('Ouch!', err);
} finally {
if (conn) { // conn assignment worked, need to close
await conn.close();
}
}
}
getEmployee(101);
PostgreSQL
npm install pg-promise
var pgp = require('pg-promise')(/*options*/)
var db = pgp('postgres://username:password@host:port/database')
db.one('SELECT $1 AS value', 123)
.then(function (data) {
console.log('DATA:', data.value)
})
.catch(function (error) {
console.log('ERROR:', error)
})
Redis
npm install redis
var redis = require('redis')
var client = redis.createClient()
client.on('error', function (err) {
console.log('Error ' + err)
})
client.set('string key', 'string val', redis.print)
client.hset('hash key', 'hashtest 1', 'some value', redis.print)
client.hset(['hash key', 'hashtest 2', 'some other value'], redis.print)
client.hkeys('hash key', function (err, replies) {
console.log(replies.length + ' replies:')
replies.forEach(function (reply, i) {
console.log(' ' + i + ': ' + reply)
})
client.quit()
})
SQL Server
npm install tedious
var Connection = require('tedious').Connection;
var Request = require('tedious').Request;
var config = {
userName: 'your_username', // update me
password: 'your_password', // update me
server: 'localhost'
}
var connection = new Connection(config);
connection.on('connect', function(err) {
if (err) {
console.log(err);
} else {
executeStatement();
}
});
function executeStatement() {
request = new Request("select 123, 'hello world'", function(err, rowCount) {
if (err) {
console.log(err);
} else {
console.log(rowCount + ' rows');
}
connection.close();
});
request.on('row', function(columns) {
columns.forEach(function(column) {
if (column.value === null) {
console.log('NULL');
} else {
console.log(column.value);
}
});
});
connection.execSql(request);
}
SQLite
npm install sqlite3
var sqlite3 = require('sqlite3').verbose()
var db = new sqlite3.Database(':memory:')
db.serialize(function () {
db.run('CREATE TABLE lorem (info TEXT)')
var stmt = db.prepare('INSERT INTO lorem VALUES (?)')
for (var i = 0; i < 10; i++) {
stmt.run('Ipsum ' + i)
}
stmt.finalize()
db.each('SELECT rowid AS id, info FROM lorem', function (err, row) {
console.log(row.id + ': ' + row.info)
})
})
db.close()
ElasticSearch
npm install elasticsearch
var elasticsearch = require('elasticsearch')
var client = elasticsearch.Client({
host: 'localhost:9200'
})
client.search({
index: 'books',
type: 'book',
body: {
query: {
multi_match: {
query: 'express js',
fields: ['title', 'description']
}
}
}
}).then(function (response) {
var hits = response.hits.hits
}, function (error) {
console.trace(error.message)
})