1. 程式人生 > >Node.js(day1)

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()是我自定義的一個方法。
  • 可以發現,這種載入資源的方式並不明智,我們每發起一次資源請求,例如一張圖片,我們就需要配置依次資源路徑,這是很繁瑣且易錯的。但目前為止上文所涉及的知識只能這樣解決。所以需要繼續升入,出門左轉。