NODE安装我就不说了,网上教程一大把,基本上下载后下一步就可以了
第一步
npm init -y 初始化项目生成json配制文件
第二步
npm i -S express 安装express框架(如果程度慢也可以用X宝的cnpm国内镜像)
第三步
新建app.js入口文件,建public静态资源文件夹,views模板文件夹
项目先跑起来
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.use(express.static('public'))
app.listen(port, () => {
console.log(`Example app listening at http://localhost:${port}`)
})
第四步
配制模板引擎(art-template npm install --save art-template express-art-template)
app.engine('art',require('express-art-template'))
app.get('/', function (req, res)) {
// express 默认会去项目中的 views 目录找 index.js
res.render('index.html', {
title: 'hello world'
})
}
app.set('views', 目录路径)
第五步
node文件修改自动启动(安装nodemon)
npm install -g nodemon
安装完 nodemon 后,就可以用 nodemon 来代替 node 来启动应用:
nodemon [your node app]
(相当于 node [your node app])
如果没有在应用中指定端口,可以在命令中指定:
nodemon ./server.js localhost 8080
可以运行 debug 模式:
nodemon --debug ./server.js 80
查看帮助,帮助里面有很多选项都是一目了然:
nodemon -h
或者 nodemon -help
正常项目开发中路由和APP文件分开管理
express生成器
通过应用生成器工具 express 可以快速创建一个应用的骨架。 1.安装以下命令
$ npm install express-generator -g
2.在当前目录创建myapp的应用,运行以下命令
$ express myapp $ cd myapp $ npm install > set DEBUG=myapp & npm start
然后在浏览器中打开 http://localhost:3000/ 网址就可以看到这个应用了。 通过 Express 应用生成器创建的应用一般都有如下目录结构:
. ├── app.js ├── bin │ └── www ├── package.json ├── public │ ├── images │ ├── javascripts │ └── stylesheets │ └── style.css ├── routes │ ├── index.js │ └── users.js └── views ├── error.jade ├── index.jade └── layout.jade 7 directories, 9 files
express路由
路由(Routing)是由一个 URI(或者叫路径)和一个特定的 HTTP 方法(GET、POST 等)组成的,涉及到应用如何响应客户端对某个网站节点的访问。每一个路由都可以有一个或者多个处理器函数,当匹配到路由时,这个/些函数将被执行。 路由的定义由如下结构组成:app.METHOD(PATH, HANDLER)。其中,app 是一个 express 实例;METHOD 是某个 HTTP 请求方式中的一个;PATH 是服务器端的路径;HANDLER 是当路由匹配到时需要执行的函数。 以下是一些常见的路由代码
var express = require('express'); var app = express(); // respond with "hello world" when a GET request is made to the homepage app.get('/', function(req, res) { res.send('hello world'); }); // POST method route app.post('/', function (req, res) { res.send('POST request to the homepage'); }); //app.all() 是一个特殊的路由方法,没有任何 HTTP 方法与其对应,它的作用是对于一个路径上的所有请求加载中间件。 app.all('/secret', function (req, res, next) { console.log('Accessing the secret section ...'); next(); // pass control to the next handler });
使用字符串模式的路由路径示例:字符 ?、+、* 和 () 是正则表达式的子集,- 和 . 在基于字符串的路径中按照字面值解释。
// 匹配 acd 和 abcd app.get('/ab?cd', function(req, res) { res.send('ab?cd'); }); // 匹配 abcd、abbcd、abbbcd等 app.get('/ab+cd', function(req, res) { res.send('ab+cd'); }); // 匹配 abcd、abxcd、abRABDOMcd、ab123cd等 app.get('/ab*cd', function(req, res) { res.send('ab*cd'); }); // 匹配 /abe 和 /abcde app.get('/ab(cd)?e', function(req, res) { res.send('ab(cd)?e'); }); //使用正则表达式的路由路径示例: // 匹配任何路径中含有 a 的路径: app.get(/a/, function(req, res) { res.send('/a/'); }); // 匹配 butterfly、dragonfly,不匹配 butterflyman、dragonfly man等 app.get(/.*fly$/, function(req, res) { res.send('/.*fly$/'); });
路由句柄
可以为请求处理提供多个回调函数,其行为类似 中间件。唯一的区别是这些回调函数有可能调用 next('route') 方法而略过其他路由回调函数。 路由句柄有多种形式,可以是一个函数、一个函数数组,或者是两者混合,如下所示
//使用多个回调函数处理路由(记得指定 next 对象): app.get('/example/b', function (req, res, next) { console.log('response will be sent by the next function ...'); next(); }, function (req, res) { res.send('Hello from B!'); }); //使用回调函数数组处理路由: 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]);
响应方法
下表中响应对象(res)的方法向客户端返回响应,终结请求响应的循环。如果在路由句柄中一个方法也不调用,来自客户端的请求会一直挂起。 方法 描述 res.download() 提示下载文件。 res.end() 终结响应处理流程。 res.json() 发送一个 JSON 格式的响应。 res.jsonp() 发送一个支持 JSONP 的 JSON 格式的响应。 res.redirect() 重定向请求。 res.render() 渲染视图模板。 res.send() 发送各种类型的响应。 res.sendFile 以八位字节流的形式发送文件。 res.sendStatus() 设置响应状态代码,并将其以字符串形式作为响应体的一部分发送。
app.route()
可使用 app.route() 创建路由路径的链式路由句柄。由于路径在一个地方指定,这样做有助于创建模块化的路由,而且减少了代码冗余和拼写错误。
app.route('/book') .get(function(req, res) { res.send('Get a random book'); }) .post(function(req, res) { res.send('Add a book'); }) .put(function(req, res) { res.send('Update the book'); });
express.Router
可使用 express.Router 类创建模块化、可挂载的路由句柄。Router 实例是一个完整的中间件和路由系统,因此常称其为一个 “mini-app”。 在 app 目录下创建名为 birds.js 的文件,内容如下:
var express = require('express'); var router = express.Router(); // 该路由使用的中间件 router.use(function timeLog(req, res, next) { console.log('Time: ', Date.now()); next(); }); // 定义网站主页的路由 router.get('/', function(req, res) { res.send('Birds home page'); }); // 定义 about 页面的路由 router.get('/about', function(req, res) { res.send('About birds'); }); module.exports = router;
然后在应用中加载路由模块:
var birds = require('./birds'); ... app.use('/birds', birds);
应用即可处理发自 /birds 和 /birds/about 的请求,并且调用为该路由指定的 timeLog 中间件。
利用 Express 托管静态文件
通过 Express 内置的 express.static 可以方便地托管静态文件,例如图片、CSS、JavaScript 文件等。 将静态资源文件所在的目录作为参数传递给 express.static 中间件就可以提供静态资源文件的访问了。例如,假设在 public 目录放置了图片、CSS 和 JavaScript 文件,你就可以:
app.use(express.static('public'));
现在,public 目录下面的文件就可以访问了。
http://localhost:3000/images/kitten.jpg http://localhost:3000/css/style.css http://localhost:3000/js/app.js http://localhost:3000/images/bg.png http://localhost:3000/hello.html
如果你的静态资源存放在多个目录下面,你可以多次调用 express.static 中间件:
app.use(express.static('public')); app.use(express.static('files'));
如果你希望所有通过 express.static 访问的文件都存放在一个“虚拟(virtual)”目录(即目录根本不存在)下面,可以通过为静态资源目录指定一个挂载路径的方式来实现,如下所示:
app.use('/static', express.static('public'));
现在,你就爱可以通过带有 “/static” 前缀的地址来访问 public 目录下面的文件了。
http://localhost:3000/static/images/kitten.jpg http://localhost:3000/static/css/style.css http://localhost:3000/static/js/app.js http://localhost:3000/static/images/bg.png http://localhost:3000/static/hello.html
常见问题
如何处理 404 ? 在 Express 中,404 并不是一个错误(error)。因此,错误处理器中间件并不捕获 404。这是因为 404 只是意味着某些功能没有实现。也就是说,Express 执行了所有中间件、路由之后还是没有获取到任何输出。你所需要做的就是在其所有他中间件的后面添加一个处理 404 的中间件。如下:
app.use(function(req, res, next) { res.status(404).send('Sorry cant find that!'); });