服务器是如何处理请求的
好的,接下来我们简单分析一下我们服务器代码中剩下的部分,也就是我们的回调函数onRequest()的主体部分。
当回调启动,我们的onRequest()函数被触发的时候,有两个参数被传入:request和response。
它们是对象,你可以使用它们的方法来处理HTTP请求的细节,并且响应请求(比如向发出请求的浏览器发挥一些东西)。
所以我们的代码就是:当收到请求时,使用response.writeHead()函数发送一个HTTP状态200和HTTP头的内容类型(content-type),使用response.write()函数在HTTP相应主体中发送文本“Hello World”。
最后,我们调用response.end()完成响应。
目前来说,我们对请求的细节并不在意,所以我们没有使用request对象。
服务端的模块放在哪里
我们在server.js文件中有一个非常基础的HTTP服务器代码,而且我提到通常我们会有一个叫index.js的文件去调用其他模块(比如server.js中的HTTP服务器模块)来引导和启动应用。
我们现在就来谈谈怎么把server.js变成一个真正的Node.js模块,使它可以被我们(还没动工)的index.js主文件使用。
也许你已经注意到,我们已经在代码中使用了模块了。像这样:
var http = require("http");
...
http.createServer(...);
Node.js中自带了一个叫做“http”的模块,我们在我们的代码中请求它并把返回值赋值给了一个本地变量。
这把我们的本地变量变成了一个拥有所有http模块所提供的公共方法的对象。
注意:给这种本地变量起一个和模块名称一样的名字是一种惯例,但是你也可以按照自己的喜好,来如下所示:
怎么使用Node.js内部模块已经很清楚了。我们怎么创建自己的模块,又怎么使用它呢?
事实上,我们不用做太多的修改。把某段代码变成模块意味着我们需要把我们希望提供其功能的部分导出到请求这个模块的脚本。
目前,我们的HTTP服务器需要导出的功能非常简单,因为请求服务器模块的脚本仅仅是需要启动服务器而已。
我们把我们的服务器脚本放到一个叫做start的函数里,然后我们会导出这个函数。
//server.js文件
var http = require("http");
function start(){
function onRequest(request,response){
console.log("Request 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;
这样我们就可以创建我们的主文件index.js并在其中启动我们的HTTP了,虽然服务器的代码还在server.js中。
创建index.js文件并写入以下内容:
var server = require("./server");
server.start();
正如你所看到的,我们可以像使用任何其他的内置模块一样使用server模块:请求这个文件并把它指向一个变量,其中已导出的函数就可以被我们使用了。
现在可以启动项目了:
node index.js
我们仍然只拥有整个应用的最初部分:我们可以接收HTTP请求。但是我们得做点什么————对于不同URL请求,服务器应该又不同的反应。
对于一个非常简单的应用来说,你可以直接在回调函数onRequest()中做这件事情。不过就像我说过的,我们应该加入一些抽象的元素,让我们的例子变得更有趣一点儿。
处理不同的 HTTP请求在我们的代码中是一个不同的部分,叫做“路由选择“————那么,我们接下来就创造一个叫做路由的模块吧。