玩转Node.js(三)
玩转Node.js(三)
上一节对于Nodejs的HTTP服务进行了较为详细的解析,而且也学会了将代码进行模块化,模块化以后每个功能都在单独的文件中,有利于代码的维护。接下来,我们要想想如何处理不同的HTTP请求,而这个处理不同的HTTP请求的东东,就是传说中的路由选择。
路由之说
首先,我们需要清楚的知道,我们要为路由提供请求的URL和其他需要的GET及POST参数,随后路由需要根据这些数据来执行相应的代码。
因此,我们需要查看HTTP请求,从中提取出请求的URL以及GET/POST参数。这一功能应当属于路由还是服务器(甚至作为一个模块自身的功能)确实值得探讨,但这里暂定其为我们的HTTP服务器的功能。
我们需要的所有数据都会包含在request对象中,该对象作为onRequest()回调函数的第一个参数传递。但是为了解析这些数据,我们需要额外的Node.JS模块,它们分别是url和querystring模块。下面的图很好的说明了数据的解析过程。
- url.parse(string).query
- |
- url.parse(string).pathname |
- | |
- | |
- ------ -------------------
- http://localhost:8888/start?foo=bar&hello=world
- --- -----
- | |
- | |
- querystring(string)["foo"] |
- |
- querystring(string)["hello"]
当然,我们也可以用querystring模块来解析POST请求体中的参数。
Just Do It
现在我们来给onRequest()函数加上一些逻辑,用来找出浏览器请求的URL路径:
- var http = require("http");
- var url = require("url");
- function start() {
- function onRequest(request, response) {
- var pathname = url.parse(request.url).pathname;
- console.log("Request for " + pathname + " received.");
- response.writeHead(200, {"Content-Type": "text/plain"});
- response.write("Hello World");
- response.end();
- }
- http.createServer(onRequest).listen(8888);
- console.log("Server has started.");
- }
- exports.start = start;
好了,我们的应用现在可以通过请求的URL路径来区别不同请求了--这使我们得以使用路由(还未完成)来将请求以URL路径为基准映射到处理程序上。
在我们所要构建的应用中,这意味着来自/start和/upload的请求可以使用不同的代码来处理。稍后我们将看到这些内容是如何整合到一起的。
现在我们可以来编写路由了,建立一个名为router.js的文件,添加以下内容:
- function route(pathname) {
- console.log("About to route a request for " + pathname);
- }
- exports.route = route;
如你所见,这段代码什么也没干,不过对于现在来说这是应该的。在添加更多的逻辑以前,我们先来看看如何把路由和服务器整合起来。
我们的服务器应当知道路由的存在并加以有效利用。我们当然可以通过硬编码的方式将这一依赖项绑定到服务器上,但是其它语言的编程经验告诉我们这会是一件非常痛苦的事,因此我们将使用依赖注入的方式较松散地添加路由模块(你可以读读Martin Fowlers关于依赖注入的大作来作为背景知识)。
首先,我们来扩展一下服务器的start()函数,以便将路由函数作为参数传递过去:
- var http = require("http");
- var url = require("url");
- function start(route) {
- function onRequest(request, response) {
- var pathname = url.parse(request.url).pathname;
- console.log("Request for " + pathname + " received.");
- route(pathname);
- response.writeHead(200, {"Content-Type": "text/plain"});
- response.write("Hello World");
- response.end();
- }
- http.createServer(onRequest).listen(8888);
- console.log("Server has started.");
- }
- exports.start = start;
同时,我们会相应扩展index.js,使得路由函数可以被注入到服务器中:
- var server = require("./server");
- var router = require("./router");
- server.start(router.route);
在这里,我们传递的函数依旧什么也没做。
如果现在启动应用(node index.js,始终记得这个命令行),随后请求一个URL,你将会看到应用输出相应的信息,这表明我们的HTTP服务器已经在使用路由模块了,并会将请求的路径传递给路由,好了,到此路由部分就此结束,执行一下你的代码看看输出吧。
PS:本博客欢迎转发,但请注明博客地址及作者,因本人水平有限,若有不对之处,欢迎指出,谢谢~
博客地址:http://www.cnblogs.com/voidy/
博客新址:http://voidy.net
<。)#)))≦
玩转Node.js(三)的更多相关文章
- 玩转Node.js(四)-搭建简单的聊天室
玩转Node.js(四)-搭建简单的聊天室 Nodejs好久没有跟进了,最近想用它搞一个聊天室,然后便偶遇了socket.io这个东东,说是可以用它来简单的实现实时双向的基于事件的通讯机制.我便看了一 ...
- 玩转Node.js(二)
玩转Node.js(二) 先来回顾上次的内容,上一次我们使用介绍了Node.js并写了第一个服务器端的Hello World程序,在这个Hello World程序中,请求自带的http模块并将其赋给h ...
- 玩转Node.js(一)
玩转Node.js(一) 在说Node.js之前,我们先来说说js,如果你也曾开发过前端,那么你一定接触到了这个叫JavaScript有趣的东西,而对于JavaScript,你只会基本的操作——为we ...
- Windows 下 玩转Node.JS
vs一直是用的比较舒服的IDE,一直期望可以支持Node.JS.终于找到了一个工具 NTVS(Node.JS Tool For VS). 主页:https://nodejstools.codeplex ...
- 玩转Node.js单元测试
代码部署之前,进行一定的单元测试是十分必要的,这样能够有效并且持续保证代码质量.而实践表明,高质量的单元测试还可以帮助我们完善自己的代码.这篇博客将通过一些简单的测试案例,介绍几款Node.js测试模 ...
- [读书笔记]了不起的node.js(三)
这周的nodejs学习内容为几个依赖包的使用,把书上的例子都敲了一遍.这篇就以例程为线索,复习一下一周的工作. 1.connect 这个例程主要是使用connect依赖包,connect提供一个中间件 ...
- node.js(三)url处理
1.parse函数的基础用法 parse函数的作用是解析url,返回一个json格式的数组,请看如下示例: var url = require('url'); url.parse('http://ww ...
- [浅学] 1、Node.js尝试_安装&运行第一个helloworld
官网:https://nodejs.org/ 介绍:Node.js® is a platform built on Chrome's JavaScript runtime for easily bui ...
- Node.js:EventEmitter类
一.EventEmitter 类 Node.js 所有的异步 I/O 操作在完成时都会发送一个事件到事件队列. Node.js里面的许多对象都会分发事件:一个net.Server对象会在每次有新连接时 ...
随机推荐
- c++ priority_queue
1.默认为大顶堆 #include <iostream> #include <queue> using namespace std; int main() { priority ...
- segment and section for c++ elf
http://blog.csdn.net/jiafu1115/article/details/12992497 写一个汇编程序保存成文本文件max.s. 汇编器读取这个文本文件转换成目标文件max.o ...
- setTimeout详解
一.setTimeout基础 setTimeout(func|code,delay); 第一个参数表示将要推迟的函数名或者一段代码,第二个参数表示推迟执行的毫秒数 eg: console.log( ...
- 1.4 配置备份策略(Policy)
1.1 配置备份策略(Policy) 一个备份策略由四部分组成. Attributes(属性) Policy是否Active Policy类型 由此Policy产生的任务的优先级 使用的Storage ...
- gearman安装实录
花了5个小时装好了gearman,问题不断,坑爹的服务器yum还坏了,悲催. 服务器系统:centos5.3 64位 gearman版本:1.1.8 安装包(相关依赖)下载 1.gearman安装包 ...
- 2017.11.18 C语言的算法分析题目
算法分析 1. 选定实验题目,仔细阅读实验要求,设计好输入输出,按照分治法的思想构思算法,选取合适的存储结构实现应用的操作. 2. 设计的结果应在Visual C++ 实验环境下实现并进行调试.(也可 ...
- frcnn_train_data_param的distort_param实现
frcnn_train_data_param frcnn_train_data_param { source: "./data/train_list.txt" root_folde ...
- 剑指offer17 合并两个排序的链表
错误代码: 最后两个if语句的目的是,最后一次迭代,两个链表中剩下的直接连接最后一次比较的数值,同时也是迭代停止的标志.虽然大if语句中比较大小得到的Node是正确的值,但每次迭代只要pHead2不为 ...
- leetCode没那么难啦 in Java (一)
前言 感觉写博客是一个很耗心力的东西T_T,简单的写了似乎没什么用,复杂的三言两语也只能讲个大概,呸呸...怎么能有这些消极思想呢QAQ!那想来想去,先开一个leetcode的坑,虽然已经工作了 ...
- js日期转换Fri Oct 31 18:00:00 UTC+0800 2008转换为yyyy-mm-dd
Date.prototype.Format = function (fmt) { var o = { "M+": this.getMonth() + 1, //月份 "d ...