成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專(zhuān)欄INFORMATION COLUMN

node練手小項(xiàng)目:在線聊天系統(tǒng)

Cristic / 2375人閱讀

摘要:處理程序在的匿名回調(diào)函數(shù)中做請(qǐng)求響應(yīng)的操作,而處理程序仍然是簡(jiǎn)單的回復(fù),只是這次是使用對(duì)象而已。為了使整個(gè)過(guò)程非阻塞,會(huì)將數(shù)據(jù)拆分成很多小的數(shù)據(jù)塊,然后通過(guò)觸發(fā)特定的事件,將這些小數(shù)據(jù)塊傳遞給回調(diào)函數(shù)。

新手node入門(mén),用這個(gè)小項(xiàng)目練練手,寫(xiě)這篇文章也是為了自己鞏固下知識(shí)。

先看效果圖:

先是讓用戶(hù)輸入名字 get yourself a nickname :)

輸入好了之后進(jìn)入,然后隨便說(shuō)點(diǎn)什么,


可以多個(gè)人在線聊天,


也可以上傳圖片:


更改字體顏色:

制作過(guò)程

文件分布:入口文件server.js

本項(xiàng)目的全代碼 https://github.com/FengNianya...(我的github倉(cāng)庫(kù))

講解:

服務(wù)器server.js
先舉一個(gè)例子:我們把我們的服務(wù)器腳本放到一個(gè)叫做 start 的函數(shù)里,然后我們會(huì)導(dǎo)出這個(gè)函數(shù)。

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;

這樣,我們現(xiàn)在就可以創(chuàng)建我們的主文件 index.js 并在其中啟動(dòng)我們的HTTP了,雖然服務(wù)器的代碼還在 server.js 中。

創(chuàng)建 index.js 文件并寫(xiě)入以下內(nèi)容:

var server = require("./server");

server.start();

正如你所看到的,我們可以像使用任何其他的內(nèi)置模塊一樣使用server模塊:請(qǐng)求這個(gè)文件并把它指向一個(gè)變量,其中已導(dǎo)出的函數(shù)就可以被我們使用了。我們現(xiàn)在可以把我們的應(yīng)用的不同部分放入不同的文件里,并且通過(guò)生成模塊的方式把它們連接到一起了。

路由:
對(duì)于不同的URL請(qǐng)求,服務(wù)器應(yīng)該有不同的反應(yīng)。

對(duì)于一個(gè)非常簡(jiǎn)單的應(yīng)用來(lái)說(shuō),你可以直接在回調(diào)函數(shù) onRequest() 中做這件事情。不過(guò)就像我說(shuō)過(guò)的,我們應(yīng)該加入一些抽象的元素,讓我們的例子變得更有趣一點(diǎn)兒。

處理不同的HTTP請(qǐng)求在我們的代碼中是一個(gè)不同的部分,叫做“路由選擇”——那么,我們接下來(lái)就創(chuàng)造一個(gè)叫做 路由 的模塊吧。
我們要為路由提供請(qǐng)求的URL和其他需要的GET及POST參數(shù),隨后路由需要根據(jù)這些數(shù)據(jù)來(lái)執(zhí)行相應(yīng)的代碼

我們需要的所有數(shù)據(jù)都會(huì)包含在request對(duì)象中,該對(duì)象作為onRequest()回調(diào)函數(shù)的第一個(gè)參數(shù)傳遞。但是為了解析這些數(shù)據(jù),我們需要額外的Node.JS模塊,它們分別是url和querystring模塊。
現(xiàn)在我們來(lái)給onRequest()函數(shù)加上一些邏輯,用來(lái)找出瀏覽器請(qǐng)求的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;

應(yīng)用現(xiàn)在可以通過(guò)請(qǐng)求的URL路徑來(lái)區(qū)別不同請(qǐng)求了--這使我們得以使用路由(還未完成)來(lái)將請(qǐng)求以URL路徑為基準(zhǔn)映射到處理程序上。

在我們所要構(gòu)建的應(yīng)用中,這意味著來(lái)自/start和/upload的請(qǐng)求可以使用不同的代碼來(lái)處理。
router.js:

function route(pathname) {
  console.log("About to route a request for " + pathname);
}

exports.route = route;

如你所見(jiàn),這段代碼什么也沒(méi)干,不過(guò)對(duì)于現(xiàn)在來(lái)說(shuō)這是應(yīng)該的。在添加更多的邏輯以前,我們先來(lái)看看如何把路由和服務(wù)器整合起來(lái)。
我們的服務(wù)器應(yīng)當(dāng)知道路由的存在并加以有效利用。我們當(dāng)然可以通過(guò)硬編碼的方式將這一依賴(lài)項(xiàng)綁定到服務(wù)器上,但是其它語(yǔ)言的編程經(jīng)驗(yàn)告訴我們這會(huì)是一件非常痛苦的事,因此我們將使用依賴(lài)注入的方式較松散地添加路由模塊
來(lái)擴(kuò)展一下服務(wù)器的start()函數(shù),以便將路由函數(shù)作為參數(shù)傳遞過(guò)去:

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;

同時(shí),我們會(huì)相應(yīng)擴(kuò)展index.js,使得路由函數(shù)可以被注入到服務(wù)器中:

var server = require("./server");
var router = require("./router");

server.start(router.route);
bash$ node index.js
Request for /foo received.
About to route a request for /foo

你將會(huì)看到應(yīng)用輸出相應(yīng)的信息,這表明我們的HTTP服務(wù)器已經(jīng)在使用路由模塊了,并會(huì)將請(qǐng)求的路徑傳遞給路由

處理函數(shù)requestHandlers的模塊

并對(duì)于每一個(gè)請(qǐng)求處理程序,添加一個(gè)占位用函數(shù),隨后將這些函數(shù)作為模塊的方法導(dǎo)出:

function start() {
  console.log("Request handler "start" was called.");
}

function upload() {
  console.log("Request handler "upload" was called.");
}

exports.start = start;
exports.upload = upload;

這樣我們就可以把請(qǐng)求處理程序和路由模塊連接起來(lái),讓路由“有路可尋”。
仔細(xì)想想,有一大堆東西,每個(gè)都要映射到一個(gè)字符串(就是請(qǐng)求的URL)上?似乎關(guān)聯(lián)數(shù)組(associative array)能完美勝任。

引用:不過(guò)結(jié)果有點(diǎn)令人失望,JavaScript沒(méi)提供關(guān)聯(lián)數(shù)組 -- 也可以說(shuō)它提供了?事實(shí)上,在JavaScript中,真正能提供此類(lèi)功能的是它的對(duì)象。
在C++或C#中,當(dāng)我們談到對(duì)象,指的是類(lèi)或者結(jié)構(gòu)體的實(shí)例。對(duì)象根據(jù)他們實(shí)例化的模板(就是所謂的類(lèi)),會(huì)擁有不同的屬性和方法。但在JavaScript里對(duì)象不是這個(gè)概念。在JavaScript中,對(duì)象就是一個(gè)鍵/值對(duì)的集合 -- 你可以把JavaScript的對(duì)象想象成一個(gè)鍵為字符串類(lèi)型的字典。

好了,最后再回到代碼上來(lái)。現(xiàn)在我們已經(jīng)確定將一系列請(qǐng)求處理程序通過(guò)一個(gè)對(duì)象來(lái)傳遞,并且需要使用松耦合的方式將這個(gè)對(duì)象注入到route()函數(shù)中。

我們先將這個(gè)對(duì)象引入到主文件index.js中:

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);

正如所見(jiàn),將不同的URL映射到相同的請(qǐng)求處理程序上是很容易的:只要在對(duì)象中添加一個(gè)鍵為"/"的屬性,對(duì)應(yīng)requestHandlers.start即可,這樣我們就可以干凈簡(jiǎn)潔地配置/start和/的請(qǐng)求都交由start這一處理程序處理。

在完成了對(duì)象的定義后,我們把它作為額外的參數(shù)傳遞給服務(wù)器,為此將server.js修改如下:

var http = require("http");
var url = require("url");

function start(route, handle) {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");

    route(handle, 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;

這樣我們就在start()函數(shù)里添加了handle參數(shù),并且把handle對(duì)象作為第一個(gè)參數(shù)傳遞給了route()回調(diào)函數(shù)。
然后我們相應(yīng)地在route.js文件中修改route()函數(shù):

function route(handle, pathname) {
  console.log("About to route a request for " + pathname);
  if (typeof handle[pathname] === "function") {
    handle[pathname]();
  } else {
    console.log("No request handler found for " + pathname);
  }
}

exports.route = route;

通過(guò)以上代碼,我們首先檢查給定的路徑對(duì)應(yīng)的請(qǐng)求處理程序是否存在,如果存在的話直接調(diào)用相應(yīng)的函數(shù)。我們可以用從關(guān)聯(lián)數(shù)組中獲取元素一樣的方式從傳遞的對(duì)象中獲取請(qǐng)求處理函數(shù),因此就有了簡(jiǎn)潔流暢的形如handle[pathname]();的表達(dá)式

有了這些,我們就把服務(wù)器、路由和請(qǐng)求處理程序在一起了

處理程序與服務(wù)器
我們采用如下這種新的實(shí)現(xiàn)方式:相對(duì)采用將內(nèi)容傳遞給服務(wù)器的方式,我們這次采用將服務(wù)器“傳遞”給內(nèi)容的方式。 從實(shí)踐角度來(lái)說(shuō),就是將response對(duì)象(從服務(wù)器的回調(diào)函數(shù)onRequest()獲?。┩ㄟ^(guò)請(qǐng)求路由傳遞給請(qǐng)求處理程序。 隨后,處理程序就可以采用該對(duì)象上的函數(shù)來(lái)對(duì)請(qǐng)求作出響應(yīng)。

原理就是如此,接下來(lái)讓我們來(lái)一步步實(shí)現(xiàn)這種方案。

先從server.js開(kāi)始:

var http = require("http");
var url = require("url");

function start(route, handle) {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");

    route(handle, pathname, response);
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

相對(duì)此前從route()函數(shù)獲取返回值的做法,這次我們將response對(duì)象作為第三個(gè)參數(shù)傳遞給route()函數(shù),并且,我們將onRequest()處理程序中所有有關(guān)response的函數(shù)調(diào)都移除,因?yàn)槲覀兿M@部分工作讓route()函數(shù)來(lái)完成。

下面就來(lái)看看我們的router.js:

function route(handle, pathname, response) {
  console.log("About to route a request for " + pathname);
  if (typeof handle[pathname] === "function") {
    handle[pathname](response);
  } else {
    console.log("No request handler found for " + pathname);
    response.writeHead(404, {"Content-Type": "text/plain"});
    response.write("404 Not found");
    response.end();
  }
}

exports.route = route;

同樣的模式:相對(duì)此前從請(qǐng)求處理程序中獲取返回值,這次取而代之的是直接傳遞response對(duì)象。

如果沒(méi)有對(duì)應(yīng)的請(qǐng)求處理器處理,我們就直接返回“404”錯(cuò)誤。

最后,我們將requestHandler.js修改為如下形式:

var exec = require("child_process").exec;

function start(response) {
  console.log("Request handler "start" was called.");

  exec("ls -lah", function (error, stdout, stderr) {
    response.writeHead(200, {"Content-Type": "text/plain"});
    response.write(stdout);
    response.end();
  });
}

function upload(response) {
  console.log("Request handler "upload" was called.");
  response.writeHead(200, {"Content-Type": "text/plain"});
  response.write("Hello Upload");
  response.end();
}

exports.start = start;
exports.upload = upload;

我們的處理程序函數(shù)需要接收response參數(shù),為了對(duì)請(qǐng)求作出直接的響應(yīng)。

start處理程序在exec()的匿名回調(diào)函數(shù)中做請(qǐng)求響應(yīng)的操作,而upload處理程序仍然是簡(jiǎn)單的回復(fù)“Hello World”,只是這次是使用response對(duì)象而已。

這時(shí)再次我們啟動(dòng)應(yīng)用(node index.js),一切都會(huì)工作的很好。

處理POST請(qǐng)求
考慮這樣一個(gè)簡(jiǎn)單的例子:我們顯示一個(gè)文本區(qū)(textarea)供用戶(hù)輸入內(nèi)容,然后通過(guò)POST請(qǐng)求提交給服務(wù)器。最后,服務(wù)器接受到請(qǐng)求,通過(guò)處理程序?qū)⑤斎氲膬?nèi)容展示到瀏覽器中。

/start請(qǐng)求處理程序用于生成帶文本區(qū)的表單,因此,我們將requestHandlers.js修改為如下形式:

function start(response) {
  console.log("Request handler "start" was called.");

  var body = ""+
    ""+
    ""+
    ""+
    ""+
    "
"+ ""+ ""+ "
"+ ""+ ""; response.writeHead(200, {"Content-Type": "text/html"}); response.write(body); response.end(); } function upload(response) { console.log("Request handler "upload" was called."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("Hello Upload"); response.end(); } exports.start = start; exports.upload = upload;

這里采用非阻塞方式處理是明智的,因?yàn)镻OST請(qǐng)求一般都比較“重” —— 用戶(hù)可能會(huì)輸入大量的內(nèi)容。用阻塞的方式處理大數(shù)據(jù)量的請(qǐng)求必然會(huì)導(dǎo)致用戶(hù)操作的阻塞。

為了使整個(gè)過(guò)程非阻塞,Node.js會(huì)將POST數(shù)據(jù)拆分成很多小的數(shù)據(jù)塊,然后通過(guò)觸發(fā)特定的事件,將這些小數(shù)據(jù)塊傳遞給回調(diào)函數(shù)。這里的特定的事件有data事件(表示新的小數(shù)據(jù)塊到達(dá)了)以及end事件(表示所有的數(shù)據(jù)都已經(jīng)接收完畢)。

我們需要告訴Node.js當(dāng)這些事件觸發(fā)的時(shí)候,回調(diào)哪些函數(shù)。怎么告訴呢? 我們通過(guò)在request對(duì)象上注冊(cè)監(jiān)聽(tīng)器(listener) 來(lái)實(shí)現(xiàn)。這里的request對(duì)象是每次接收到HTTP請(qǐng)求時(shí)候,都會(huì)把該對(duì)象傳遞給onRequest回調(diào)函數(shù)。
如下所示:

request.addListener("data", function(chunk) {
  // called when a new chunk of data was received
});

request.addListener("end", function() {
  // called when all chunks of data have been received
});

問(wèn)題來(lái)了,這部分邏輯寫(xiě)在哪里呢? 我們現(xiàn)在只是在服務(wù)器中獲取到了request對(duì)象 —— 我們并沒(méi)有像之前response對(duì)象那樣,把 request 對(duì)象傳遞給請(qǐng)求路由和請(qǐng)求處理程序。

在我看來(lái),獲取所有來(lái)自請(qǐng)求的數(shù)據(jù),然后將這些數(shù)據(jù)給應(yīng)用層處理,應(yīng)該是HTTP服務(wù)器要做的事情。因此,我建議,我們直接在服務(wù)器中處理POST數(shù)據(jù),然后將最終的數(shù)據(jù)傳遞給請(qǐng)求路由和請(qǐng)求處理器,讓他們來(lái)進(jìn)行進(jìn)一步的處理。

因此,實(shí)現(xiàn)思路就是: 將data和end事件的回調(diào)函數(shù)直接放在服務(wù)器中,在data事件回調(diào)中收集所有的POST數(shù)據(jù),當(dāng)接收到所有數(shù)據(jù),觸發(fā)end事件后,其回調(diào)函數(shù)調(diào)用請(qǐng)求路由,并將數(shù)據(jù)傳遞給它,然后,請(qǐng)求路由再將該數(shù)據(jù)傳遞給請(qǐng)求處理程序。

還等什么,馬上來(lái)實(shí)現(xiàn)。先從server.js開(kāi)始:

var http = require("http");
var url = require("url");

function start(route, handle) {
  function onRequest(request, response) {
    var postData = "";
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");

    request.setEncoding("utf8");

    request.addListener("data", function(postDataChunk) {
      postData += postDataChunk;
      console.log("Received POST data chunk ""+
      postDataChunk + "".");
    });

    request.addListener("end", function() {
      route(handle, pathname, response, postData);
    });

  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

上述代碼做了三件事情: 首先,我們?cè)O(shè)置了接收數(shù)據(jù)的編碼格式為UTF-8,然后注冊(cè)了“data”事件的監(jiān)聽(tīng)器,用于收集每次接收到的新數(shù)據(jù)塊,并將其賦值給postData 變量,最后,我們將請(qǐng)求路由的調(diào)用移到end事件處理程序中,以確保它只會(huì)當(dāng)所有數(shù)據(jù)接收完畢后才觸發(fā),并且只觸發(fā)一次。我們同時(shí)還把POST數(shù)據(jù)傳遞給請(qǐng)求路由,因?yàn)檫@些數(shù)據(jù),請(qǐng)求處理程序會(huì)用到。

上述代碼在每個(gè)數(shù)據(jù)塊到達(dá)的時(shí)候輸出了日志,這對(duì)于最終生產(chǎn)環(huán)境來(lái)說(shuō),是很不好的(數(shù)據(jù)量可能會(huì)很大,還記得吧?),但是,在開(kāi)發(fā)階段是很有用的,有助于讓我們看到發(fā)生了什么。

我建議可以嘗試下,嘗試著去輸入一小段文本,以及大段內(nèi)容,當(dāng)大段內(nèi)容的時(shí)候,就會(huì)發(fā)現(xiàn)data事件會(huì)觸發(fā)多次。
再來(lái)點(diǎn)酷的。我們接下來(lái)在/upload頁(yè)面,展示用戶(hù)輸入的內(nèi)容。要實(shí)現(xiàn)該功能,我們需要將postData傳遞給請(qǐng)求處理程序,修改router.js為如下形式:

function route(handle, pathname, response, postData) {
  console.log("About to route a request for " + pathname);
  if (typeof handle[pathname] === "function") {
    handle[pathname](response, postData);
  } else {
    console.log("No request handler found for " + pathname);
    response.writeHead(404, {"Content-Type": "text/plain"});
    response.write("404 Not found");
    response.end();
  }
}

exports.route = route;

然后,在requestHandlers.js中,我們將數(shù)據(jù)包含在對(duì)upload請(qǐng)求的響應(yīng)中:

function start(response, postData) {
  console.log("Request handler "start" was called.");

  var body = ""+
    ""+
    ""+
    ""+
    ""+
    "
"+ ""+ ""+ "
"+ ""+ ""; response.writeHead(200, {"Content-Type": "text/html"}); response.write(body); response.end(); } function upload(response, postData) { console.log("Request handler "upload" was called."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("You"ve sent: " + postData); response.end(); } exports.start = start; exports.upload = upload;

好了,我們現(xiàn)在可以接收POST數(shù)據(jù)并在請(qǐng)求處理程序中處理該數(shù)據(jù)了。

我們最后要做的是: 當(dāng)前我們是把請(qǐng)求的整個(gè)消息體傳遞給了請(qǐng)求路由和請(qǐng)求處理程序。我們應(yīng)該只把POST數(shù)據(jù)中,我們感興趣的部分傳遞給請(qǐng)求路由和請(qǐng)求處理程序。在我們這個(gè)例子中,我們感興趣的其實(shí)只是text字段。

我們可以使用此前介紹過(guò)的querystring模塊來(lái)實(shí)現(xiàn):

var querystring = require("querystring");

function start(response, postData) {
  console.log("Request handler "start" was called.");

  var body = ""+
    ""+
    ""+
    ""+
    ""+
    "
"+ ""+ ""+ "
"+ ""+ ""; response.writeHead(200, {"Content-Type": "text/html"}); response.write(body); response.end(); } function upload(response, postData) { console.log("Request handler "upload" was called."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("You"ve sent the text: "+ querystring.parse(postData).text); response.end(); } exports.start = start; exports.upload = upload;

處理文件上傳
這里我們要用到的外部模塊是Felix Geisend?rfer開(kāi)發(fā)的node-formidable模塊。它對(duì)解析上傳的文件數(shù)據(jù)做了很好的抽象。 其實(shí)說(shuō)白了,處理文件上傳“就是”處理POST數(shù)據(jù) —— 但是,麻煩的是在具體的處理細(xì)節(jié),所以,這里采用現(xiàn)成的方案更合適點(diǎn)。

使用該模塊,首先需要安裝該模塊。Node.js有它自己的包管理器,叫NPM。它可以讓安裝Node.js的外部模塊變得非常方便。通過(guò)如下一條命令就可以完成該模塊的安裝:

npm install formidable
npm info build Success: formidable@1.0.9
npm ok
var querystring = require("querystring"),
    fs = require("fs");

function start(response, postData) {
  console.log("Request handler "start" was called.");

  var body = ""+
    ""+
    ""+
    ""+
    ""+
    "
"+ ""+ ""+ "
"+ ""+ ""; response.writeHead(200, {"Content-Type": "text/html"}); response.write(body); response.end(); } function upload(response, postData) { console.log("Request handler "upload" was called."); response.writeHead(200, {"Content-Type": "text/plain"}); response.write("You"ve sent the text: "+ querystring.parse(postData).text); response.end(); } function show(response, postData) { console.log("Request handler "show" was called."); fs.readFile("/tmp/test.png", "binary", function(error, file) { if(error) { response.writeHead(500, {"Content-Type": "text/plain"}); response.write(error + " "); response.end(); } else { response.writeHead(200, {"Content-Type": "image/png"}); response.write(file, "binary"); response.end(); } }); } exports.start = start; exports.upload = upload; exports.show = show;

我們還需要將這新的請(qǐng)求處理程序,添加到index.js中的路由映射表中:

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;
handle["/show"] = requestHandlers.show;

server.start(router.route, handle);

好,最后我們要的就是:

在/start表單中添加一個(gè)文件上傳元素
將node-formidable整合到我們的upload請(qǐng)求處理程序中,用于將上傳的圖片保存到/tmp/test.png
將上傳的圖片內(nèi)嵌到/uploadURL輸出的HTML中
需要在upload處理程序中對(duì)上傳的文件進(jìn)行處理,這樣的話,我們就需要將request對(duì)象傳遞給node-formidable的form.parse函數(shù)。

但是,我們有的只是response對(duì)象和postData數(shù)組??礃幼樱覀冎荒懿坏貌粚equest對(duì)象從服務(wù)器開(kāi)始一路通過(guò)請(qǐng)求路由,再傳遞給請(qǐng)求處理程序。 或許還有更好的方案,但是,不管怎么說(shuō),目前這樣做可以滿(mǎn)足我們的需求。

到這里,我們可以將postData從服務(wù)器以及請(qǐng)求處理程序中移除了 —— 一方面,對(duì)于我們處理文件上傳來(lái)說(shuō)已經(jīng)不需要了,另外一方面,它甚至可能會(huì)引發(fā)這樣一個(gè)問(wèn)題: 我們已經(jīng)“消耗”了request對(duì)象中的數(shù)據(jù),這意味著,對(duì)于form.parse來(lái)說(shuō),當(dāng)它想要獲取數(shù)據(jù)的時(shí)候就什么也獲取不到了。(因?yàn)镹ode.js不會(huì)對(duì)數(shù)據(jù)做緩存)

我們從server.js開(kāi)始 —— 移除對(duì)postData的處理以及request.setEncoding (這部分node-formidable自身會(huì)處理),轉(zhuǎn)而采用將request對(duì)象傳遞給請(qǐng)求路由的方式:

    var http = require("http");
var url = require("url");

function start(route, handle) {
  function onRequest(request, response) {
    var pathname = url.parse(request.url).pathname;
    console.log("Request for " + pathname + " received.");
    route(handle, pathname, response, request);
  }

  http.createServer(onRequest).listen(8888);
  console.log("Server has started.");
}

exports.start = start;

接下來(lái)是 router.js —— 我們不再需要傳遞postData了,這次要傳遞request對(duì)象:

function route(handle, pathname, response, request) {
  console.log("About to route a request for " + pathname);
  if (typeof handle[pathname] === "function") {
    handle[pathname](response, request);
  } else {
    console.log("No request handler found for " + pathname);
    response.writeHead(404, {"Content-Type": "text/html"});
    response.write("404 Not found");
    response.end();
  }
}

exports.route = route;
還沒(méi)寫(xiě)完,有空繼續(xù)更新,也可以看下載個(gè)
 》

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/89579.html

相關(guān)文章

  • nodejs練手爬蟲(chóng)+API測(cè)試

    摘要:知乎日?qǐng)?bào)代理首先感謝提供的分析使用詳情請(qǐng)參考他提供的參數(shù)和地址代理轉(zhuǎn)發(fā)的使用為前綴進(jìn)入代理路由啟動(dòng)界面圖像獲取后為圖像分辨率,接受任意的格式,為任意非負(fù)整數(shù),返回值均相同返回值示例最新消息等具體參考提供的分析中的使用方式以及參數(shù)含義。 項(xiàng)目說(shuō)明 這是一個(gè)基于express的node后端API服務(wù),當(dāng)時(shí)只是想抓取字幕組網(wǎng)站的下載資源,以備以后通過(guò)nas的方式去自動(dòng)下載關(guān)注的美劇。不過(guò)后來(lái)...

    bigdevil_s 評(píng)論0 收藏0
  • 基于 Vue2+Node+mongoDB 的前后端分離全棧練手項(xiàng)目

    摘要:本文源碼簡(jiǎn)介之前剛?cè)腴T(mén)并做好了一個(gè)簡(jiǎn)而全的純?nèi)彝暗捻?xiàng)目,數(shù)據(jù)都是本地模擬請(qǐng)求的詳情請(qǐng)移步這里為了真正做到數(shù)據(jù)庫(kù)的真實(shí)存取,于是又開(kāi)始入門(mén)了并以此來(lái)為之前的頁(yè)面寫(xiě)后臺(tái)數(shù)據(jù)接口。 本文源碼:Github 簡(jiǎn)介: 之前剛?cè)腴T(mén)vue并做好了一個(gè)簡(jiǎn)而全的純vue2全家桶的項(xiàng)目,數(shù)據(jù)都是本地 json 模擬請(qǐng)求的;詳情請(qǐng)移步這里:vue-proj-demo 為了真正做到數(shù)據(jù)庫(kù)的真實(shí)存取,于是又...

    jay_tian 評(píng)論0 收藏0
  • 全棧最后一公里 - Node.js 項(xiàng)目的線上服務(wù)器部署與發(fā)布

    摘要:沒(méi)有耐心閱讀的同學(xué),可以直接前往學(xué)習(xí)全棧最后一公里。我下面會(huì)羅列一些,我自己錄制過(guò)的一些項(xiàng)目,或者其他的我覺(jué)得可以按照這個(gè)路線繼續(xù)深入學(xué)習(xí)的項(xiàng)目資源。 showImg(https://segmentfault.com/img/bVMlke?w=833&h=410); 本文技術(shù)軟文,閱讀需謹(jǐn)慎,長(zhǎng)約 7000 字,通讀需 5 分鐘 大家好,我是 Scott,本文通過(guò)提供給大家學(xué)習(xí)的方法,...

    Nosee 評(píng)論0 收藏0
  • vue+socket.io+express+mongodb 實(shí)現(xiàn)簡(jiǎn)易多房間在線群聊

    摘要:項(xiàng)目簡(jiǎn)介主要是通過(guò)做一個(gè)多人在線多房間群聊的小項(xiàng)目來(lái)練手全棧技術(shù)的結(jié)合運(yùn)用。編譯運(yùn)行開(kāi)啟服務(wù),新建命令行窗口啟動(dòng)服務(wù)端,新建命令行窗口啟動(dòng)前端頁(yè)面然后在瀏覽器多個(gè)窗口打開(kāi),注冊(cè)不同賬號(hào)并登錄即可進(jìn)行多用戶(hù)多房間在線聊天。 項(xiàng)目簡(jiǎn)介 主要是通過(guò)做一個(gè)多人在線多房間群聊的小項(xiàng)目、來(lái)練手全棧技術(shù)的結(jié)合運(yùn)用。 項(xiàng)目源碼:chat-vue-node 主要技術(shù): vue2全家桶 + socket....

    android_c 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<