摘要:每个中间件可以从实例,接收三个参数,依次为对象代表请求对象代表回应,回调函数代表下一个中间件。等方法除了在回调函数内部判断请求的网址,方法也允许将请求网址写在第一个参数。
前言
利用node直接实现服务器是运用http模块,Express和Koa都是在其上做的封装,
这篇wiki只是想直观的看看封装前后基本使用上的不同,先不去考虑深入的东西。
var http = require("http"); http.createServer(function(req, res) { // 主页 if (req.url == "/") { res.writeHead(200, { "Content-Type": "text/html" }); res.write("Welcome to the homepage!"); res.end("Welcome to the homepage!"); } // About页面 else if (req.url == "/about") { res.writeHead(200, { "Content-Type": "text/html" }); res.end("Welcome to the about page!"); } // 404错误 else { res.writeHead(404, { "Content-Type": "text/plain" }); res.end("404 error! File not found."); } }).listen(8080, "localhost");
http模块的createServer直接就能创建一个服务器的实例,然后调用实例的listen方法,传入监听的端口与主机就ok了,
处理函数把http的request和response对象作为两个参数进行操作。
实现路由: 通过请求的url来判断
写响应头部:res.writeHead方法
写响应body: res.write
结束响应: res.end
1.2 处理Post请求var http = require("http"); http.createServer(function (req, res) { var content = ""; req.on("data", function (chunk) { content += chunk; }); req.on("end", function () { res.writeHead(200, {"Content-Type": "text/plain"}); res.write("You"ve sent: " + content); res.end(); }); }).listen(8080);
监听req的data和end事件,data事件会在数据接收过程中,每收到一段数据就触发一次,
接收到的数据被传入回调函数。end事件则是在所有数据接收完成后触发。
简单说,中间件(middleware)就是处理HTTP请求的函数。它最大的特点就是,一个中间件处理完,再传递给下一个中间件。
App实例在运行过程中,会调用一系列的中间件。每个中间件可以从App实例,接收三个参数,
依次为request对象(代表HTTP请求)、response对象(代表HTTP回应),next回调函数(代表下一个中间件)。
每个中间件都可以对HTTP请求(request对象)进行加工,并且决定是否调用next方法,将request对象再传给下一个中间件。
一个不进行任何操作、只传递request对象的中间件,就是下面这样。
function uselessMiddleware(req, res, next) { next(); }
上面代码的next就是下一个中间件。如果它带有参数,则代表抛出一个错误,参数为错误文本。
function uselessMiddleware(req, res, next) { next("出错了!"); }
抛出错误以后,后面的中间件将不再执行,直到发现一个错误处理函数为止。
use是express注册中间件的方法。
app.use(function(request, response, next) { console.log("In comes a " + request.method + " to " + request.url); next(); }); app.use(function(request, response) { response.writeHead(200, { "Content-Type": "text/plain" }); response.end("Hello world! "); });2.2 路由的实现 2.2.1 request.url
可以利用request.url属性,判断请求的网址,从而返回不同的内容,实现路由。
app.use(function(request, response, next) { if (request.url == "/") { response.writeHead(200, { "Content-Type": "text/plain" }); response.end("Welcome to the homepage! "); } else { next(); } }); app.use(function(request, response, next) { if (request.url == "/about") { response.writeHead(200, { "Content-Type": "text/plain" }); } else { next(); } });2.2.2 use等方法
除了在回调函数内部判断请求的网址,use方法也允许将请求网址写在第一个参数。
这代表,只有请求路径匹配这个参数,后面的中间件才会生效。无疑,这样写更加清晰和方便。
app.use("/home", function(request, response, next) { response.writeHead(200, { "Content-Type": "text/plain" }); response.end("Welcome to the homepage! "); });
针对不同的请求,use可以有不同的别名,分别对应http的方法,包括get post put post delete。
2.2.3 利用Express.Routervar router = express.Router(); router.get("/", function(req, res) { res.send("首页"); }); router.get("/about", function(req, res) { res.send("关于"); }); app.use("/", router);
router能够自由挂载和直接把路由写在use上相比,能够为程序书写带来更大的灵活性。
2.3 处理POST请求为什么要多带带说这个post请求,因为获取request的body不是能够通过request的一个body属性就可以的,
通过http处理post的请求中我们可以看到,需要通过监听request的data和end方法进行拼接,因为body可能分多次传过来。
利用框架的好处就是有人写了中间件,可以直接用。Express中处理body的中间件用body-parser
var bodyParser = require("body-parser"); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false }));
body-parser提供了一下几种转换格式
JSON body parser
Raw body parser
Text body parser
URL-encoded form body parser
利用中间件以后,可以直接利用request.body直接获取转换后的body。
router.post("/testpost", function(req, res, next) { console.log("testpost"); res.send(req.body); });三、Koa框架
一个Koa应用就是一个对象,包含了一个middleware数组,这个数组由一组Generator函数组成。
这些函数负责对HTTP请求进行各种加工,比如生成缓存、指定代理、请求重定向等等。
var koa = require("koa"); var app = koa(); app.use(function *(){ this.body = "Hello World"; }); app.listen(3000);
可以看到,Koa框架和Express框架使用起来很相似。那么重点说的应该是Koa框架的不同之处:
1.中间件用Generator函数,所以中间件利用了Generator函数的中断等待特性
2.把request和response对象封装到了context中,通过this访问,所以操作的api会有不同。
3.1 中间件Koa中间件与Express的不同就在于它是Generator函数,Generator函数内部使用yield命令,将程序的执行权转交给下一个中间件,
即yield next,要等到下一个中间件返回结果,才会继续往下执行,所以是嵌套执行的顺序。
app.use(function *(next){ console.log(">> one"); yield next; console.log("<< one"); }); app.use(function *(next){ console.log(">> two"); this.body = "two"; console.log("<< two"); });
输出:
>> one >> two << one << two
所以当需要有异步操作的时候,我们可以用yield,将控制权交给它,不必将处理逻辑写在回调函数中。
Generator函数会返回一个遍历器对象,yield语句就是暂停的标识,Koa框架则会自动的遍历Generator函数,直到结束,返回http请求。
所以在何时返回http请求,koa没有像http模块和Express框架那样显示的指定,比如调用res.end,res.send等方法来结束http响应。
koa则是在执行完所有中间件以后自动的返回http请求。不会等待未完成的异步操作
3.2路由两种方式
一种是用this.path做判断
let koa = require("koa") let app = koa() // normal route app.use(function* (next) { if (this.path !== "/") { return yield next } this.body = "hello world" });
一种是用koa-router插件,类似于Express的use和一系列http动词方法。
var app = require("koa")(); var Router = require("koa-router"); var myRouter = new Router(); myRouter.get("/", function *(next) { this.response.body = "Hello World!"; }); app.use(myRouter.routes()); app.listen(3000);3.3 context对象
中间件当中的this表示上下文对象context,代表一次HTTP请求和回应,即一次访问/回应的所有信息,都可以从上下文对象获得。
context对象封装了request和response对象,并且提供了一些辅助方法。每次HTTP请求,就会创建一个新的context对象。
context对象的全局属性。
request:指向Request对象
response:指向Response对象
req:指向Node的request对象
req:指向Node的response对象
app:指向App对象
state:用于在中间件传递信息。
3.4 处理Post的请求其实就是如何获取reauest中的body,利用中间件co-body,处理后可以通过this.request.body访问
// application/json var body = yield parse.json(this); // application/x-www-form-urlencoded var body = yield parse.form(this); // text/plain var body = yield parse.text(this);
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/82716.html
摘要:接口用于接收服务器发送的事件。因此,是目前来说最佳的选择。最大特点就是,服务器可以主动向客户端推送消息,客户端也可以主动向服务器发送信息,是一种不受限的全双工通信。若是,则交给的回调函数处理,否则,还是走正常的回调的路子。 使用 WebSocket 的理由 传统的http协议有一个根本性的缺陷,那就是请求只能由客户端向服务器发起,服务器接收到请求后再进行响应,把数据返回给客户端。也就是...
摘要:是解释性语言因服务端的应用,而贯通了前后台。关于和声明的变量和声明的变量整体,会被提升到当前作用域的顶部。做后台服务端,处理请求的代码,得自己实现了。为提高下载速度,可通过来切换镜像源。 JS是解释性语言,因node服务端的应用,而贯通了前后台。 【ES6】 关于var和let var: 1.var声明的变量和function声明的变量整体,会被提升到当前作用域的顶部。 2...
摘要:接上次挖的坑,对相关的源码进行分析第一篇。和同为一批人进行开发,与相比,显得非常的迷你。在接收到一个请求后,会拿之前提到的与来创建本次请求所使用的上下文。以及如果没有手动指定,会默认指定为。 接上次挖的坑,对koa2.x相关的源码进行分析 第一篇。 不得不说,koa是一个很轻量、很优雅的http框架,尤其是在2.x以后移除了co的引入,使其代码变得更为清晰。 express和ko...
阅读 3060·2021-11-23 10:09
阅读 2042·2021-10-26 09:51
阅读 952·2021-10-09 09:44
阅读 3876·2021-10-08 10:04
阅读 2728·2021-09-22 15:14
阅读 3562·2021-09-22 15:02
阅读 992·2021-08-24 10:03
阅读 1700·2019-12-27 12:14