Express框架:

一、   Express框架

Express框架是后台的Node框架,类似于JS中的jquery。

#原生Node开发会有很多问题:

1呈递静态页面很不方便,需要处理每个HTTP请求,还要考虑304问题

2路由处理代码不直观清晰,需要写很多正则表达式和字符串函数

3不能集中精力写业务,要考虑很多其他的东西

我们自己可以把第一天的作业,就是那个静态文件服务封装成为模块。封装的越多,就自己做出了类似Express的东西。

Express的哲学就是在你的想法和服务器之间充当薄薄的一层。这并不意味着它不够健壮,或者没有足够的有用特性,而是尽量少干预你,让你充分表达自己的思想,同时提供一些有用的东西。

http://www.expressjs.com.cn/

整体感知,Express框架:

1.expres惊艳的路由能力

var express = require('express');

var app = express();

app.get('/', (req, res) => {

res.send('你好');

});

app.get('/haha', (req, res) => {

res.send('这是haha页面,哈哈哈');

});

app.get(/^\/student\/([\d]{6})$/, (req, res) => {

//正则中的()表示分组提取 第[0]个

res.send('学生信息,学号' + req.params[0]);

});

//冒号可以被req得到

app.get('/teacher/:gonghao', (req, res) => {

//

res.send('老师信息,工号' + req.params.gonghao);

});

app.listen(2888);

 2.Express静态文件的伺服能力。

const express = require('express');

var app = express();

//使用中间件:(在当前目录的public文件夹下有index.html 这时GET / 的时候会自动读出index.html)

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

app.get('/haha', (req, res) => {

res.send('haha');

});

app.listen(2888);

3.Express与模板引擎的配合,直观清晰,天呐撸

haha.ejs:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<meta name="viewport" content="width=device-width, initial-scale=1.0">

<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Document</title>

</head>

<body>

<h1>哈哈哈哈</h1>

<ul>

<% for(var i = 0;i<news.length;i++){%>

<li>

<%= news[i] %>

</li>

<% } %>

</ul>

</body>

</html>

3.js:

const express = require('express');

var app = express();

app.set('view engine','ejs');

app.get('/',(req,res)=>{

//默认就是views/文件夹下

res.render('haha.ejs',{

news:['我是小新闻啊','我也是啊','天啦噜']

})

});

app.listen(2888);

二、路由

我们学习的是Express4.x和Express3.x差别非常大。

用get请求访问一个网址

app.get(‘网址’,(req,res)=>{

});

app.post(‘网址’,(req,res)=>{

});

restful

如果想除了这个网址的任何methods的请求

app.all(‘/’,(req,res)=>{

})

app.get(‘/AAb’,(req,res)=>{

res.send(‘你好’);

})

实际上小写的访问也行。

所有的GET参数,?都已经被忽略。 锚点#也被忽略

你路由到/a,实际/a?id=2&sex=nan 也能被处理

正则表达式可以被使用。正则表达式中,未知部分用圆括号分组,然后可以用req.params[0]、req.params[1]来获取。

app.get(/^\/student\/([\d]{10})$/,(req,res)=>{

res.send(‘学生信息,学号’ + req.params[0]);

});

冒号是更推荐的写法。

const express = require('express');

var app = express();

app.get('/:username/:oid',(req,res)=>{

var username = req.params.username;

var oid = req.params.oid;

res.write(username);

res.end(oid);

});

app.listen(2888);

表单可以自己提交到自己:

05.js:

const express = require('express');

const app = express();

//设置模板引擎

app.set('view engine', 'ejs');

app.get('/', (req, res) => {

res.render('form');

});

app.post('/', (req, res) => {

//将数据添加进入数据库

res.send('成功');

});

app.listen(2888);

适合进行RESTful路由设计。

RESTful路由设计

/students

get 读取学生信息

post 修改学生信息

delete 删除学生信息

【用express来实现非常简单】

app.get、app,post、app,delete...

总结:这节课比较重点的地方是 路由,路由的话,app.get(‘\’)这里面可以写正则表达式,用()来捕获,也可以写:,最后用req.params[0] 或者req.params.xxx来获取,推荐的是使用:冒号的方式。

一、          中间件

//这个就叫做中间件

app.get('/',(req,res)=>{

console.log('2');

});

顾名思义,中间件(middleware)作为请求和响应之间的中间人,用于处理HTTP请求,返回特定结果。

如果我的get、post回调函数中,没有next参数,那么匹配上第一个中间件后就不会往下继续匹配了,如果向往下匹配的话,那么需要写next();

app.get('/',(req,res,next)=>{

console.log('1');

next();

});

//这个就叫做中间件

app.get('/',(req,res)=>{

console.log('2');

});

下面两个路由,感觉没有关系:

app.get('/:username/:id', (req, res) => {

console.log('1');

res.send('用户信息'+req.params.username);

});

//这个就叫做中间件

app.get('/admin/login', (req, res) => {

console.log('2');

res.send('管理员登陆');

});

但是实际上冲突了,因为admin可以当作用户名 login可以当作id。

解决方法1:交换位置,也就是说,express中所有的路由(中间件)的顺序至关重要。

匹配上第一个,就不会往下匹配了。具体的网上写,抽象的往下写。

主要规则:(写路由表的时候,越具体的越要往上写,越抽象的越要往下写)

解决方法2:使用next()

const express = require('express');

var app = express();

var a = 100;

//这个就叫做中间件

app.get('/admin/login', (req, res) => {

var username = req.params.username;

//检索数据库,如果username不存在,那么next

if(检索数据库){

console.log('2');

res.send('管理员登陆');

}

else{

next();

}

});

app.get('/:username/:id', (req, res) => {

console.log('1');

res.send('用户信息'+req.params.username);

});

app.listen(2888);

路由get、post这些东西,就是中间件,中间件讲究顺序,匹配上第一个之后就不会往后匹配了。除非写了next()之后才能够继续往后匹配。

app.use:

举例,如果我GET /admin 返回’hello world’ 那么我GET /admin/asd 也会返回’hello world’.

app.use('/admin', function(req, res, next) {

// GET 'http://www.example.com/admin/new/asd/asd'

console.log(req.originalUrl); // '/admin/new'

console.log(req.baseUrl); // '/admin'

console.log(req.path); // '/new/asd/asd'

next();

});

app.use也是一个中间件,它与get和post的不同是,它的网址不是精确匹配的,而是有拓展的。

所以:

app.use(‘/’,(req,res)=>{

})

//这样就会出现骚操作。所有的请求是/的扩展,所以…

但是要写next();否则会卡在这个中间件。

app.use(‘/’,(req,res)=>{

console.log(‘haha’);

next();

})

还可以这样简写:

//不写就相当于‘/’

app.use((req,res)=>{

console.log(‘haha’);

next();

})

app.use()就给我们增加一些特定功能的便利场所。

自带的静态服务:

app.use(express.static(‘./public’));

//使用了app.use这个方法,使用了封装好的express.static这个中间件,这个静态服没有next方法(),一般把它放在代码的上边部分,防止做路由的时候和现有文件冲突,

比如你有一个image文件夹就没必要再做/image路由转到别的地方。直接读这个文件夹就好了。

//其实似乎这两个广义地讲都叫中间件..

(但是我们其实编程时候不怎么使用app.use方法,因为这很不MVC)

app.use(‘/jingtai’,express.static(‘./public’));

·大多数情况下,渲染内容用res.render(),将会根据views中的模板文件进行渲染。如果不想使用view文件夹,想自己设置文件夹名字,那么app.set(‘views’,’…’)

·如果想写一个快速测试页,当然可以使用res.send()。这个函数 将根据内容,自动帮我们设置了Content-Type头部和200状态吗。send()只能用一次,和end一样。和end不一样在哪里?能够自动设置MIME

·如果想使用不同的状态吗,可以:

res.status(404).send(‘Sorry,we cannot find that’)

·如果想使用不同的Content-Type,可以:

res.set(‘Content-Type’,’text,html’);

app.set…

(…这些都可以被set,如果需要使用请详细查看官网文档)

四、GET请求和POST请求

·GET请求的参数在URL中,在原生Node中,需要使用url模块来识别参数字符串。在Express中,不需要使用url模块来parse了,可以直接使用req.query对象。

·POST请求在express中不能直接获得,必须使用body-parser模块,使用后,将可以用req.body得到参数。但是如果表单中含有文件上传,那么还是需要使用formidable模块。

req.query打印出的是一个对象,比如GET \?a=1&b=2 返回的就是:{a:1,b:2}

POST引擎需要引用body-parser中间件

req.body打印出一个对象

12.js:

const express = require('express');

var app = express();

var bodyParser = require('body-parser');

app.set('view engine', 'ejs');

app.get('/', (req, res) => {

res.render('form');

});

app.use(bodyParser.urlencoded({ extended: false }));

app.post('/', (req, res) => {

res.send(req.body);

});

app.listen(3333);

捋捋api:

主要来看一下最后一个Route,Route是个啥.

以下内容摘抄自网络:

———————————————————————————————————————

当你调用 express() 方法时,就创建了一个 Application。事实上这个 Application 也只不过是对 Router 的一个轻量级封装而已。

每个 Application 内部都创建了一个 Router,大部分对 Application 的操作实际上都被重定向到了这个内部的 Router 上而已。而 Application 所做的,只不过是在这个 Router 的基础上添加了一些额外的便捷 API 而已。

举个例子,当你调用 app.get(...) 或者 app.use(...) 的时候,实际上真正调用的是 app._router.get(...) 或者 app_router.use(...)。

所以,Application 和 Router 的区别便很清楚了,Application 是 Router 的一个“包装”,而 Router 才是“核心”。

router.get is only for defining subpaths. Consider this example:

var router = express.Router();
 
app.use('/first', router); // Mount the router as middleware at path /first
 
router.get('/sud', smaller);
 
router.get('/user', bigger);

Now if you will open /first/sud in your browser, then smaller function will get called. If you will open first/user, then bigger will gets called. In short, app.use('/first', router) mounts the middleware at path /first, then router.get sets the subpath accordingly.

But if we instead use:

app.use('/first', fun);
 
app.get('/sud', bigger);
 
app.get('/user', smaller);

Now if you will open /first in your browser then fun will get called and for /sud, bigger will get called and for /user, the function smaller will get called. ...but remember here for /first/sud, no function will get called.

回答者要传达的意思是:“路由级别的中间件,可以作为app级别的中间件的扩展,从而减小app级别路径处理的臃肿,提高可维护性和扩展性”。

强行比喻一下:

产品经理通过应用级别的中间件,控制一级路径;然后各个项目经理,在此基础上,自己通过路由级别的中间件,控制二级路径(项目经理不用考虑产品经理是怎么处理一级路径的)。

——————————————————————————————————

小小相册项目:

//前端语言与后端语言

本质区别:前端是在用户电脑运行,后端是在服务器运行

Node中全是回调函数,所以我们自己封装的函数,里面如果有异步方法,比如I/O,那么就要用回调函数的方法封装。

错误

res.render(“index”,

{“name”:student.getDetailById(234234).name});

正确

student.getDetailByXuHao(234234,function(detail){

res.render(“index”,{

“name”:detail.name

})

})

Node_进阶_3的更多相关文章

  1. Node_进阶_8

    Node进阶第八天 一.复习 Node.js特点:单线程.异步I/O(非阻塞I/O).事件驱动(事件环). 适合的程序:就是没有太多的计算,I/O比较多的业务. 举例:留言本.考试系统.说说.图片裁切 ...

  2. Node_进阶_7

    Node进阶第七天 一.复习 一.索引   数据库中,根据一个字段的值,来寻找一个文档,是很常见的操作.比如根据学号来找一个学生.这个学号是唯一的.只要有学号,就能唯一确认一个学生的文档.学号这个属性 ...

  3. Node_进阶_6

    Node进阶第六天 一.复习 cookie是在res中设置,req中读取的.第一次的访问没有cookie. cookie的存储大小有限,kv对儿.对用户可见,用户可以禁用.清除cookie.可以被篡改 ...

  4. Node_进阶_5

    Node进阶第五天 为什么mysql不用开mongod –dbpath xx… 答:因为mysql会在”服务”中运行,也就是开机时自动启动并且长久驻扎在内存中了. mongodb其实也能通过设置来设成 ...

  5. Node_进阶_4

    Node进阶第四天 一.传统数据库技术回顾 数据库就是存储数据的,那么存储数据用txt就行了啊,为什么要有数据库? 理由之一:数据库有行.列的概念,数据有关系,数据不是散的. 老牌数据库,比如Mysq ...

  6. React-Native进阶_3.触摸高亮显示TouchableHighlight

    在安卓原生ListView  点击 其中一个子视图时,会有高亮效果,这个效果在ReactNative 中通过TouchableHighlight 实现,具体使用如下 4.触摸高亮显示 Touchabl ...

  7. Node_进阶_2

    第二天 一.复习: Node.js开发服务器.数据.路由.本地关心效果,交互. Node.js实际上是极客开发出的一个小玩具,不是银弹.有着别人不具备的怪异特点: 单线程.非阻塞I/O.事件驱动. 实 ...

  8. Node_进阶_1

    第一天 1.1简介 Node.js简介 V8引擎本身就是用于Chrome浏览器的JS解释部分,Ryan Dahl把这个V8搬到了服务器上,用于做服务器的软件. Node.js是一个让Javascrip ...

  9. PythonI/O进阶学习笔记_3.2面向对象编程_python的继承(多继承/super/MRO/抽象基类/mixin模式)

    前言: 本篇相关内容分为3篇多态.继承.封装,这篇为第二篇 继承. 本篇内容围绕 python基础教程这段: 在面向对象编程中,术语对象大致意味着一系列数据(属性)以及一套访问和操作这些数据的方法.使 ...

随机推荐

  1. CDR中怎么绘制一个漂亮的球衣?

    cdr中怎么绘制一个漂亮的球衣?想要绘制一个漂亮的球衣,该怎么绘制呢?下面我们就来看看cdr绘制漂亮的球衣的教程,需要的朋友可以参考下: 1.画一个长方形,增加节点,移动节点,变形成如图 2.直线变曲 ...

  2. elementUI 上传.csv文件不成功 导入功能

    前言:element上传excel文件   导入功能 目标:点击导入,将excel表格的数据填充到表格. <el-upload class="upload-demo" :ac ...

  3. JS数组中的indexOf方法

    前言 这两天在家中帮朋友做项目,项目中使用了数组的indexOf 方法,找到了一篇文章,感觉非常不错,顺便整理下以防链接丢失. 相信说到 indexOf 大家并不陌生,判断字符串是否包涵子字符串时特别 ...

  4. VUE:class与style强制绑定

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. div,span等标签支持focus/blur事件

    <div tabindex="0" hidefocus="true" onfocus='alert("得到焦点");' onblur= ...

  6. 【BZOJ 1433】[ZJOI2009]假期的宿舍

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 把每个人都分为左边和右边两个人 xi,yi 如果第i个人不回家或者是外校学生 那么它可以和他认识的人连一条容量为1的边(前提是这个认 ...

  7. 如何在 Linux 上安装 Nginx (源码安装)

    如何在 Linux( CentOS ) 上安装 Nginx 1.下载 nginx 链接 : https://pan.baidu.com/s/1sll0Hrf 密码 : xnem 2.安装 gcc ( ...

  8. CC2540/CC2541 : Set the Peripheral Being Advertising while It is Being Connected

    There is possible to set your CC254X be scanable when it is in connection. But, based on my test,the ...

  9. C++编写绚丽的界面

    近期项目特别的操蛋,要用C++写出各种变态界面,今晚上赶工总算有了一点小的收货. 因为没有时间去写博文 ,等项目期完了  准备 写一系列 怎样在C++/win32/mfc开发高质量  可扩展界面组建 ...

  10. 深搜解Riding the Fences

    Riding the Fences Farmer John owns a large number of fences that must be repairedannually. He traver ...