@Wangww0925
2019-08-07T08:02:22.000000Z
字数 9643
阅读 303
NodeJs
Express框架是后台的javascript框架
原生Node开发,会发现有很多问题。比如:
1. 呈递静态页面很不方便,需要处理每个HTTP请求,还要考虑304问题
2. 路由处理代码不直观清晰,需要写很多个条件分支
总之原生Node开发不能集中精力写业务,要考虑很多其他的东西。所以,express可以帮助我们解决上述问题
npm install express --save--save参数,表示自动修改package.json文件,自动添加依赖项
var express = require("express");var app = express(); // 创建服务器console.log(app)
app.get(url, callback(req,res)); - get请求访问网址app.post(url, callback(req,res)); - post访问网址app.all(url, callback(req,res)); - 不管是get请求还是post请求use()listen()set()[EventEmitter: app]_events: { mount: [Function: onmount] },_eventsCount: 1,_maxListeners: undefined,setMaxListeners()getMaxListeners()emit()addListener()on()prependListener()once()prependOnceListener()removeListener()off()removeAllListeners()listeners()rawListeners()listenerCount()eventNames()init()defaultConfiguration()lazyrouter()handle()route()engine()param()path()enabled()disabled()enable()disable()acl()bind()checkout()connect()copy()delete()head()link()lock()'m-search'()merge()mkactivity()mkcalendar()mkcol()move()notify()options()patch()propfind()proppatch()purge()put()rebind()report()search()source()subscribe()trace()unbind()unlink()unlock()unsubscribe()del()render()request()response()cache()engines()settings {'x-powered-by': true,etag: 'weak','etag fn': [Function: generateETag],env: 'development','query parser': 'extended','query parser fn': [Function: parseExtendedQueryString],'subdomain offset': 2,'trust proxy': false,'trust proxy fn': [Function: trustNone],view: [Function: View],views:'C:\\Users\\Dooban000\\Desktop\\node\\6.5-06\\NodeJs_06\\views','jsonp callback name': 'callback'},locals {settings {}},mountpath: '/'
Request 对象 - 表示 HTTP 请求,包含了请求查询字符串,参数,内容,HTTP 头部等属性req.app - 当callback为外部文件时,用req.app访问express的实例req.originalUrl - 获取原始请求URL【req.baseUrl + req.path】,例 /login/frsgrg/gtrgrtg/gtgtg/gwgreq.baseUrl - 获取路由当前安装的URL路径,例 /loginreq.path - 获取请求路径,例 /frsgrg/gtrgrtg/gtgtg/gwgreq.params - 获取路由的parametersreq.query - 获取URL的查询参数串req.body & req.cookies - 获得「请求主体」/ Cookiesreq.fresh & req.stale - 判断请求是否还「新鲜」req.hostname & req.ip - 获取主机名和IP地址req.protocol - 获取协议类型req.route - 获取当前匹配的路由req.subdomains - 获取子域名req.accepts() - 检查可接受的请求的文档类型req.acceptsCharsets & req.acceptsEncodings & req.acceptsLanguages - 返回指定字符集的第一个可接受字符编码req.get() - 获取指定的HTTP请求头req.is() - 判断请求头Content-Type的MIME类型=======================================================================================Response 对象 - 表示 HTTP 响应,即在接收到请求时向客户端发送的 HTTP 响应数据res.app - 同req.app一样res.send() - 结束请求,传送HTTP响应res.append() - 追加指定HTTP头res.cookie(name, value, [option]) - 设置Cookie; opition: domain / expires / httpOnly / maxAge / path / secure / signedres.clearCookie() - 清除Cookieres.download() - 传送指定路径的文件res.get() - 返回指定的HTTP头res.json() - 传送JSON响应res.jsonp() - 传送JSONP响应res.location() - 只设置响应的Location HTTP头,不设置状态码或者close responseres.redirect() - 设置响应的Location HTTP头,并且设置状态码302res.render(view,[locals],callback) - 渲染一个view,同时向callback传递渲染后的字符串,如果在渲染过程中有错误发生next(err)将会被自动调用。callback将会被传入一个可能发生的错误以及渲染后的页面,这样就不会自动输出了。res.sendFile(path, [options], [fn]) - 传送指定路径的文件 -会自动根据文件extension设定Content-Typeres.set() - 设置HTTP头,传入object可以一次设置多个头;res.set()在res.append()后将重置之前设置的头res.status() - 设置HTTP状态码res.type() - 设置Content-Type的MIME类型
url路由路径,可以忽略大小写
可以采用链式调用方法处理不同的路由
如果想使用不同的状态码,可以 res.status(404).send('内容');
如果想使用不同的Content-Type,可以 res.set('Content-Type', 'Mime类型');
app.get(url, callback(req,res));
node 执行文件 test.js
var express = require("express");var app = express(); // 创建服务器app.get("/",(req,res)=>{res.send("<h1>hahahaha</h1>");})app.listen(8081);
执行命令
npm install express --savenode test.js
app.post(url, callback(req,res))
node 执行文件 test.js
var express = require("express");var app = express(); // 创建服务器app.post("/",(req,res)=>{res.send("<h1>post请求</h1>")})app.listen(8081);
执行命令
npm install express --savenode test.js
app.all(url, callback(req,res));
node 执行文件 test.js
var express = require("express");var app = express(); // 创建服务器app.all("*",(req,res)=>{res.status(404).send("<h1>404</h1>")})app.listen(8081);
执行命令
npm install express --savenode test.js
表示模糊匹配路由路径内容,可以匹配任何路由路径的形式为/sfdsfdsf/sdsfsf
可以把 content 和 content1 当做变量 然后通过 req.params 来拿到值
req.params 为对象
node 执行文件 test.js
var express = require("express");var app = express(); // 创建服务器app.get("/:number/:id",(req,res)=>{console.log(req.params);var number = req.params.number;var id = req.params.id;res.send(`${number}:::::${id}`);})app.listen(8081);
执行命令
npm install express --savenode test.js
效果图

app.use(url,callback(req,res));
匹配路由前缀,只要前缀匹配成功,那么所有的路由都会被执行
当路由路径为根路径的时候,express规定路由路径参数可以不写 【app.use("/",(req,res)=>{}) => app.use((req,res)=>{})】
var express = require("express");var app = express();app.use((req,res)=>{res.send("aaa");})app.listen(8081);
PS:res.send() 可以发送任何数据类型的数据,原生的nodejs发送的数据类型只能为字符串或者buffer
PS:自动添加请求头text/html
index.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><h1>hello world</h1></body></html>
node 执行文件
var express = require("express");var fs = require("fs");var app = express(); // 创建服务器app.all("/",(req,res)=>{fs.readFile("./index.html",(err,data)=>{if(err){console.log(err);}if(!err){res.send(data.toString());}})});app.listen(8081);
效果图:

PS:自动添加请求头application/json
json是一种数据传输格式,json包含有json数组和json对象
在发送对象或者数组的时候已经将数组或者对象进行转换为json字符串了
node 执行文件
var express = require("express");var app = express(); // 创建服务器app.get("/",(req,res)=>{res.send([1,2,3,4,5,6]);})app.listen(8081);
效果图:

PS:自动添加请求头 applicaiton/octet-stream
index.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><h1>hello world</h1><img src="1.jpg" alt=""></body></html>
node 执行文件
var express = require("express");var fs = require("fs");var app = express(); // 创建服务器app.all("/",(req,res)=>{fs.readFile("./index.html",(err,data)=>{if(err){console.log(err);}if(!err){// res.send(data)时,如果读取流中存在路径,则浏览器会下载res.send(data);}})});app.listen(8081);
效果图

因为在send的时候,express会自动识别内容,然后添加相对用的content-type类型。
当发送的内容为buffer对象的时候,添加的content-type类型为 application/octet-stream。但是浏览器不能识别解析这一种mime类型,所以只能下载
node执行文件
var express = require("express");var app = express(); // 创建服务器// app.use("/", express.static("./project")); // "/" 可以省略app.use(express.static("./project"));app.listen(8081);
效果图

需要在应用中进行如下设置才能让 Express 渲染模板文件
app.set('views', './test'); // 默认为这个目录; views: 放模板文件的目录app.set('view engine', 'ejs'); // 显示指定模板引擎为ejs; 【view engine: 模板引擎】
test/index.ejs
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><h1>ejs</h1><ul><% for(var i=0;i<arr.length;i++){ %><li><%= arr[i] %></li><% } %></ul></body></html>
node执行文件
var express = require("express");var app = express(); // 创建服务器app.set("views","./test"); // 设置ejs模板存放的地方app.set("view engine","ejs"); // 显示指定模板引擎为ejsvar data = {arr:['html',"css",'javascript']}app.get("/",(req,res)=>{res.render("index", data); // 数据替换})app.listen(8081);
效果图

在express中路由路径的匹配是从上往下匹配的,如果有一个匹配成功,就不会再去匹配下面的路由路径,这个时候如果想让他继续去匹配其他的路由就需要使用next中间件了
中间件可以预先处理所有请求再转交给特定的路由来进行处理。
node执行文件
var express = require("express");var app = express();// 中间件app.get("/",(req,res,next)=>{console.log("11111")res.send("hahaha");next();})app.get("/",(req,res)=>{console.log("22222");})app.listen(8081);
效果图

node执行文件
var express = require("express");var app = express();// /teacher/123456// /student/1234567891app.get("/:username/:id",(req,res,next)=>{var username = req.params.username;var id = req.params.id;if(username == "teacher" && /^\d{6}$/.test(id)){res.send(`查询的老师id为:${id}`);return;}if(username == "student" && /^\d{10}$/.test(id)){res.send(`查询的学生id为:${id}`);return;}next();})app.get("/:username/:id",(req,res,next)=>{res.send("输入错误");next();})app.get("*",(req,res)=>{res.status(404).send("no resource")})app.listen(8081);
效果图

GET请求的参数在URL中,在原生Node中,需要使用url模块来识别参数字符串。在Express中,不需要使用url模块了。可以直接使用req.query对象。
POST请求在express中不能直接获得,必须使用body-parser模块。使用后,将可以用req.body得到参数。但是如果表单中含有文件上传,那么还是需要使用formidable模块
var bodyParser = require('body-parser')app.post("/login",bodyParser.urlencoded({extended:false}),(req,res)=>{res.send(req.body);})
index.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>Document</title></head><body><form action="/login" method="get">用户名: <input type="text" name="username"><br>密码: <input type="text" name="password"><br><button>提交</button></form></body></html>
PS:根据请求方式修改 method="get"
node 执行的文件
var express = require("express");var fs = require("fs");var bodyParser = require('body-parser')var app = express();app.get("/",(req,res)=>{fs.readFile("./index.html",(err,data)=>{res.send(data.toString());})})// get请求app.get("/login",(req,res)=>{res.send(req.query);})// post请求app.post("/login",bodyParser.urlencoded({extended:false}),(req,res)=>{res.send(req.body);})app.listen(8081);
get请求效果图

post请求效果图

作者 wendy
2019 年 1月 21日