Node.js 知识记录

What

Node.js事实上就是另外一种上下文,它允许在后端(脱离浏览器环境)运行JavaScript代码。

Process

  • 我们需要提供Web页面,因此需要一个HTTP服务器
  • 对于不同的请求,根据请求的URL,我们的服务器需要给予不同的响应,因此我们需要一个路由,用于把请求对应到请求处理程序(request handler)
  • 当请求被服务器接收并通过路由传递之后,需要可以对其进行处理,因此我们需要最终的请求处理程序
  • 路由还应该能处理POST数据,并且把数据封装成更友好的格式传递给请求处理入程序,因此需要请求数据处理功能
  • 我们不仅仅要处理URL对应的请求,还要把内容显示出来,这意味着我们需要一些视图逻辑供请求处理程序使用,以便将内容发送给用户的浏览器
  • 最后,用户需要上传图片,所以我们需要上传处理功能来处理这方面的细节

Demo

// 第一行请求(require)Node.js自带的 http 模块,并且把它赋值给 http 变量。
var http = require("http"); 
// 接下来我们调用http模块提供的函数: createServer 。
// 这个函数会返回一个对象,这个对象有一个叫做 listen 的方法
// 这个方法有一个数值参数,指定这个HTTP服务器监听的端口号。
http.createServer(function(request, response) {
// onRequest() 函数被触发的时候,有两个参数被传入: request 和 response 。
// 它们是对象,你可以使用它们的方法来处理HTTP请求的细节,并且响应请求(比如向发出请求的浏览器发回一些东西)
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello World");
  // 使用 response.write() 函数在HTTP相应主体中发送文本“Hello World"。
  response.end();
}).listen(8888);

事件驱动

给某个方法传递了一个函数,这个方法在有相应事件发生时调用这个函数来进行 回调 。
在创建完服务器之后,即使没有HTTP请求进来、我们的回调函数也没有被调用的情况下,我们的代码还继续有效。
当收到请求时,使用 response.writeHead() 函数发送一个HTTP状态200和HTTP头的内容类型(content-type),使用 response.write() 函数在HTTP相应主体中发送文本“Hello World"。最后,我们调用 response.end() 完成响应。

行为驱动执行

将函数作为参数传递不仅仅出于技术上的考量也是个哲学问题

路由

为路由提供请求的URL和其他需要的GET及POST参数,随后路由需要根据这些数据来执行相应的代码
查看HTTP请求,从中提取出请求的URL以及GET/POST参数。这一功能应当属于路由还是服务器(甚至作为一个模块自身的功能)确实值得探讨,但这里暂定其为我们的HTTP服务器的功能

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有不同的处理方式。例如处理/start的“业务逻辑”就应该和处理/upload的不同。

创建一个叫做requestHandlers的模块,并对于每一个请求处理程序,添加一个占位用函数,随后将这些函数作为模块的方法导出:

function start() {
  console.log("Request handler 'start' was called.");
}
function upload() {
  console.log("Request handler 'upload' was called.");
}
exports.start = start;
exports.upload = upload;

结合到一起

var server = require("./server");
var router = require("./router");
var requestHandlers = require("./requestHandlers");
var handle = {}
handle["/"] = requestHandlers.start;
handle["/start"] = requestHandlers.start;
handle["/upload"] = requestHandlers.upload;
server.start(router.route, handle);

阻塞和非阻塞

Node.js可以在不新增额外线程的情况下,依然可以对任务进行并行处理 —— Node.js是单线程的。它通过事件轮询(event loop)来实现并行操作,对此,我们应该要充分利用这一点 —— 尽可能的避免阻塞操作,取而代之,多使用非阻塞操作。

child_process

hild_process模块,主要是用的child_process.spawn(),需要注意的是,这个函数只会创建异步进程。异步进程的话,不会阻塞主进程的执行。它其实是个很好的东西,有了它,我们可以执行非常耗时的shell操作而无需迫使我们的应用停下来等待该操作。

实际使用

让我们来看看如何处理POST请求(非文件上传),之后,我们使用Node.js的一个用于文件上传的外部模块。之所以采用这种实现方式有两个理由。
第一,尽管在Node.js中处理基础的POST请求相对比较简单
第二,用Node.js来处理文件上传(multipart POST请求)是比较复杂的

处理POST 请求

POST请求一般都比较“” —— 用户可能会输入大量的内容。用阻塞的方式处理大数据量的请求必然会导致用户操作的阻塞
为了使整个过程非阻塞,Node.js会将POST数据拆分成很多小的数据块,然后通过触发特定的事件,将这些小数据块传递给回调函数。这里的特定的事件有data事件(表示新的小数据块到达了)以及end事件(表示所有的数据都已经接收完毕)。
data和end事件的回调函数直接放在服务器中,在data事件回调中收集所有的POST数据,当接收到所有数据,触发end事件后,其回调函数调用请求路由,并将数据传递给它,然后,请求路由再将该数据传递给请求处理程序。

index.js 是主文件
sever.js 是HTTP服务器模块,当回调启动时候,onRequest()函数被触发,两个参数传入request和response–> 使用它们的方法来处理HTTP请求的细节,并且响应请求。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值