Node.js(day1)
1、什麼是Node.js
Node.js Everywhere
我們可以從官網的介紹來分析:node中文網 | node引文網
Node.js® 是一個基於 Chrome V8 引擎 的 JavaScript 執行時。
- 瀏覽器引擎可以解析並執行js,google的v8引擎速度很快,所以node.js可以在脫離瀏覽器的情況下解析並執行js程式碼。
- 我們平常所用的js為瀏覽器中的js,而node.js可以看做服務端的js,所以node.js不是一門新語言也非新框架,而是js執行時。
- 可以簡單的將node.js理解為使用js語言進行web伺服器開發。(為了實現這些功能,node.js提供了一些特別的api)
node.js使用事件驅動、非阻塞I/O模型使得其輕量、高效。
node.js的包生態系統,
npm
是世界上最大的開源庫生態系統。
- 絕大多數javascript包都存放在了npm上,以方便開發者安裝使用。
2、Node.js能做什麼
- Web伺服器後臺
- 命令列工具(如npm、git等都屬於命令列工具,對於前端開發來說使用最多的也是node.js提供的命令列工具)
3、使用命令列解析js檔案
寫一個簡單的js檔案,
var str = 'hello node';
conole.log(str);
隨意命名,比如hello.js。(注意,不能使用node.js命名,否則會開啟文字而不會解析執行)
然後在檔案存放處開啟命令列,使用node指令執行即可:
4、使用Node構建web伺服器
我們已經知道Node可以解析js檔案了,而js也可以進行web伺服器搭建,所以我們只需要使用Node.js提供的相關api來搭建伺服器,再用命令列去解析執行即可。
//類似我們需要使用某些物件一樣,需要使用關鍵字進行New,在Node.js中我們使用require()方法進行模組載入(Node中的模組就相當於具有特殊功能的物件) //要構建一個web伺服器需要使用http模組 var http = require('http'); //使用http模組建立webServer var server = http.createServer(); //設定埠號 server.listen(8888,function(){ console.log("埠號啟用成功!"); }); //伺服器request事件:請求時觸發 server.on('request',function(request,response){ console.log("已經收到請求!"+'請求路徑為:'+request.url);//一些請求資訊 response.write("雷好,我係~渣渣輝!");//響應 response.end("該幹嘛幹嘛去");//告知瀏覽器響應結束,不必等待 }); console.log("webServer at localhost://88888");
然後我們開啟瀏覽器輸入:localhost://8888或127.0.0.1://8888就可以訪問了。
總結一下:
- Node.js的一些特殊功能,比如建立伺服器,是普通js沒有的,我們把這些具有特殊功能的物件稱作模組,要使用這些模組,需要使用
require()
方法進行裁入。 - http模組可以建立伺服器。使用
createServer([options][, requestListener])
方法可以建立並返回一個伺服器物件,然後我們就可以進行相應設定。 - 伺服器的
listen()
方法為伺服器設定埠號。 - 伺服器物件有很多事件,比如
request事件
在瀏覽器請求該伺服器時觸發,利用回撥函式可以進行request處理和response響應。 response.end()
方法告知瀏覽器響應結束,否則瀏覽器會一直等待響應。- 響應資料只能是二進位制資料或字串。
5、Node.js中的JavaScript
- EcmaScript(不包含BOM、DOM)
- 核心模組
- 第三方模組
- 自定義模組
5.1核心模組
Node.js為JavaScript提供了很多伺服器級別的api,這些api絕大多數都被包裝到了一個具名的核心模組中,比如:
檔案操作的fs
(File System)模組、http
服務建立的http模組、路勁操作的path
模組、作業系統資訊的os
模組等。
而我們需要使用這些核心模組就需要使用require()
方法進行獲取。
5.2自定義模組
Node.js中的模組有三種:
- 具名的核心模組
- 第三方模組
- 自定義模組
其中使用者自定義的模組又叫檔案模組,也就是那些js檔案。
我們知道,在命令列中node指令只能編譯執行一個js檔案,但是我們的專案不可能只有一個js檔案,同樣的,js檔案也是模組,所以我們需要在某個檔案中使用require()
方法解析執行檔案模組。
比如我現在有以下三個js檔案:
//a.js檔案
console.log('a start');
require('./b.js');//解析執行b.js
console.log('a end');
//b.js檔案
console.log('b start');
require('./c.js');//解析執行c.js
console.log('b end');
//c.js檔案
console.log('CCCCCC');
執行結果如下:
值得注意的點:
- 在Node.js中沒有全域性作用域,只有檔案作用域。也就是說每個js檔案的作用域都是分離的,互不影響。
- 相對路勁必須寫
./
;檔案字尾可以省略。
既然每個檔案中的變數互不影響,那麼如果我們需要使用到某個檔案內部的變數時又該如何獲取呢?其實require()方法除了解析執行檔案模組之外還能返回檔案模組自帶的exports物件
,該物件預設為空{}。
所以我們只需要在檔案模組中將需要到處的值傳入exports物件中即可:
var b = require('./b');//載入b檔案
console.log(b);//輸出b模組匯出的物件
var str = '雷好,我係渣渣輝';
function add(x,y){
return x+y;
}
exports.str = str;
exports.add = add;
執行:
6、響應內容的型別Content-Type
上文中我們響應的中文可能在瀏覽器中顯示是亂碼,這是因為Node.js預設的響應型別是utf-8,而瀏覽器不知道,如果瀏覽器預設編碼不是utf-8就會產生亂碼。
response物件在響應的時候可以設定相關引數,比如響應頭,響應內容的型別,而編碼方式的資訊就由Content-Type
來設定。
//設定響應頭引數。響應型別為普通文字,編碼方式為utf-8
response.setHeader('Content-Type','text/plain;charset=utf-8');
示例:
var http = require('http');
var server = http.createServer();
server.listen(8888);
//伺服器request事件:請求時觸發
server.on('request',function(request,response){
var url = request.url;
var str = '<h1>如果你看得清我,說明我沒有亂碼!</h1>'
if(url == '/plain'){
response.setHeader('Content-Type','text/plain;charset=utf-8');//返回普通文字
}else if(url == '/html'){
response.setHeader('Content-Type','text/html;charset=utf-8');//返回html文字
}else{
str = 'please use url /plain or /html and get the response!'
}
response.end(str);
});
console.log("webServer running at localhost://88888");
7、fs核心檔案
fs全稱File System,用於操作檔案,基本的兩個功能為為讀檔案和寫檔案。
7.1使用fs讀檔案:readFile()
//使用require方法載入fs模組
var fs = require('fs');
fs.readFile('hello.js',function(error,data){
if(error){
console.log('檔案讀取失敗!');
return;
}
console.log(data.toString());
});
- 使用fs的readFile()方法,第一個引數為檔案地址,第二個引數為回撥函式。
- 回撥函式有兩個引數,error和data,當檔案讀取成功時,error返回null,data返回檔案的
二進位制資料
;當檔案讀取失敗時,error返回包含錯誤資訊的物件,data返回undefined。 - 使用data.toString()方法可以講二進位制資料轉化為utf-8編碼字串。
7.2使用fs寫檔案:writeFile()
var fs = require('fs');
fs.writeFile('hello.txt','大噶好,I\'m 渣渣輝',function(error){
if(!error){
console.log("檔案寫入成功!");
}else{
console.log("檔案寫入失敗!");
}
});
- 使用fs.writeFile()方法寫入檔案。第一個引數為檔案地址及檔名,第二個引數為檔案的文字資訊,可以是字串,也可以是二進位制資料,第三個引數為回撥函式。
7.3案例:利用fs檔案的讀寫操作實現檔案複製
邏輯很簡單,將讀取的檔案資料寫入新的檔案中即可
var fs = require('fs');
fs.readFile('jinx.jpeg',function(error,data){
if(error){
console.log('檔案讀取失敗!');
}else{
//將讀取的資料寫入新的檔案中
fs.writeFile('jinx(copy).jpeg',data,function(error){
if(!error){
console.log("檔案寫入成功!");
}else{
console.log("檔案寫入失敗!");
}
});
}
});
8、案例:使用Node載入index.html並實現簡單頁面跳轉
由於檔案過多這裡不再展示,假設這是一個本地專案,
我們希望使用Node.js來搭建伺服器,並在伺服器上執行我們的專案。
大家伺服器很簡單,關鍵點在於我們需要根據請求路勁來載入相應的資原始檔,這些上面的案例都能實現。類似這樣:
我們根據request.url
使用fs核心模組
來載入檔案,並設定相應的Content-Type
在瀏覽器中正確裁入檔案型別。
- openfile()是我自定義的一個方法。
- 可以發現,這種載入資源的方式並不明智,我們每發起一次資源請求,例如一張圖片,我們就需要配置依次資源路徑,這是很繁瑣且易錯的。但目前為止上文所涉及的知識只能這樣解決。所以需要繼續升入,出門左轉。