一、什麼是node?
node是js的運作環境,可以讓js脫離前端單獨運作
二、node的特點
1、單線程
無論是多少事情,都是一個線程去完成
單線程的優點:沒有了多線程建立線程和銷毀線程的開銷,排程多線程也是需要消耗資源的。多線程,有多少事情就有多少線程去完成。
單線程的特點:無法利用多核cup,一旦陳谷被惡意的行為挂起,那麼整個程式崩潰。
2、非堵塞I/O,在i/o進行的時候,線程不等待。 阻塞I/O: 在i/o進行的時候,線程等待。
I:input
O:output 讀取檔案、連接配接資料庫讀取資料庫、操作CD光牒驅動器等等都叫做I/O。它們比較起記憶體和cpu的運作速度來說,是特别慢的。也就是說如果線程讓硬碟讀取一個比較大的檔案。并且等待讀取完畢并交給記憶體之後再去做别的事情。那麼也就是說線程在等待讀取(I/O)完成
3 事件驅動
事件驅動與非阻塞I/O是連着的一個事情。非阻塞I/O确實可以讓線程在I/O進行的時候去做其它的事情,但是有個問題。線程去做了其它的事情,萬一這個時候I/O完成了呢?怎麼知道I/O什麼時候完成?I/O完成的時候會觸發一個事件,這個事件驅動着線程回來繼續做下面的事情。
三、子產品
3.1 内置核心子產品 ——http
http子產品是用來搭建伺服器的。
IncomingMessage : request
OutgoingMessage : response
METHODS : 這是一個數組裡面裝着所有的http請求方式
STATUS_CODES :是一個對象,對象的每個key都是一個狀态碼,對象的value是該狀态碼的含義
Server :是一個方法,用于将其它的服務轉化成http服務
createServer : 是一個方法,用于建立服務
3.2 檔案系統——file system
Fs子產品是用來操作檔案的。所有的相關操作都是fs的方法。
建立檔案并追加内容

3.3 url子產品
Parse方法:将一個url路徑,轉成一個對象,對象有各種屬性對應的就是不同的部分。
http://www.icketang.com/html/shouye/index.html?username=wanglaowu&password=123#123
上面的url字元串經過url子產品的parse方法處理完會轉變成以下對象
{
Protocol:http,
Host:www.icketang.com,
Hostname:www.icketang.com,
Port:null,
Pathname:html/shouye/index.html,
Search:?username=wanglaowu&password=123,
Query: username=wanglaowu&password=123,
Hash:#123,
Href:
}
parse方法還有第二個參數,是一個布爾值。預設為false。 如果為true,那麼将會把傳回的對象中的query選項轉為一個對象。
url.format(urlObj)
format這個方法是将傳入的url對象程式設計一個url字元串并傳回參數:urlObj指一個url對象
url解析get方法
Url子產品是專門處理前端送出過來的請求位址的。
如何處理get請求:
1判斷請求的方式 處理
如何處理post請求:
1判斷請求的方式
if(req.method===”post”){
//code...
}
2給req綁定data事件
var str=“”;
req.on(“data”,function(data_chunk){
//這個事件是post每發送一次資料,就會觸發一次,回調函數中的參數是data_chunk表示的是這一次所 傳遞的資料。
str += data_chunk;
})
req.on(“end”,function(){
//這個事件是post發送資料完畢之後才最終觸發一次。是以說先觸發1次或者多次data事件,再觸發1次end事件。後續代碼要寫在end事件中
3.4 檔案上傳 formidable
3.5 express
Express是第三方子產品,用來快速開發一個伺服器。
express中間件
Express内置的唯一中間件就是靜态資源中間件。
req是前端傳遞過來的請求。
Req.query表示的是get請求攜帶的資料
包含在路由每個查詢字元串參數的屬性的對象。如果沒有查詢字元串,它是空的對象,{}。
Req.params表示的是從pathname上獲得的資料
包含映射到指定的路線“參數”屬性的對象。例如,如果你有路線/user/:name,那麼“名”屬性可作為req.params.name。這個對象預設{}。
Req.body 表示的是post請求攜帶的資料 (必須得先應用中間件:body-parser);
包含請求主體送出的鍵值對。預設情況下它是undefined。除非你使用了body-parser
例如:app.use(body_parser.urlencoded({extended:false}));
Body-parser中間件:
Ejs模闆
Express允許我們像使用php那樣(或者說是underscore的模闆)使用ejs模闆。
Ejs模闆必須是一個檔案,檔案的拓展名是ejs => index.ejs
内部的内容還是大體上是html隻不過有一部分是<%=variable%>組成的。當渲染的時候,會從字典中與variable進行比對。并替換。
Ejs模闆不需要引入app.js主程式檔案。但是必須要在express中聲明,而且還要放到node_modules中,這樣express就能夠找到ejs子產品了:
app.set(“view engine”,”ejs”);
App.set表示要設定什麼東西,第一個參數就是要設定的内容。第二個參數是對第一個參數更詳細的說明.
聲明完了之後,就可以在某個路由的響應中使用res.render()進行渲染ejs模闆了。
條件:第一個參數是要渲染的模闆檔案。(該檔案必須要存在與主程式同級目錄下的views檔案夾中)
第二個參數是渲染該模闆檔案的字典。
4.自定義子產品
在NodeJs中,每一個js檔案天生就是一個子產品。
每個子產品都能夠向外暴露一些東西。
核心子產品暴露的内容是十分重要的,比如:http子產品負責搭建伺服器。Fs子產品負責操作檔案等
自定義子產品,随便定義。
子產品化開發有什麼好處呢?
每個子產品隻負責提供功能。不會将變量注冊到全局作用域下。
我們自己定義了一個js檔案。可以通過require函數将它引入到其它的js檔案中。
方法是:
var app = require(“./app.js”);
此時,必須在同級目錄下有app.js這個檔案
另一個方法是:将app.js放在同級目錄下的node_modules檔案夾中(或者上級、上上級、一直到根目錄)
此時可以這麼寫了: var app = require(“app.js”);
此時的查找順序是隻會查找node_modules。
向外暴露有三種方式: