nodejs 開發,手把手開始第一個服務器程序(原生)



此文章為原生 nodejs  ,僅做學習使用

想學習 express 和 koa2 的小伙伴請繞路

此文章適合有HTML 和css 、js 基礎的小伙伴看哦

如果能幫到你,榮幸之至

文章純手打,如有紕漏歡迎下方留言

 

寫在前面:

  127.0.0.1 : 回環地址,每一台電腦都有該ip,指向當前使用的電腦

  nodejs 中的 js 與 瀏覽器中 js 的區別:

    瀏覽器中 js :ECMAScript 核心 + DOM + BOM

    Node 中的 js :ECMAScript 核心 + 全局成員 + 模塊系統(系統模塊、第三方模塊、自定義模塊)

    全局成員: setTimeout、setInterval、console.log() 等。

    注意 :這幾個名稱和功能雖然和瀏覽器中的一樣,但是是 Nodejs 自己實現的,與瀏覽器無關

 

安裝nodejs

  官網: https://Nodejs.org/en/

  中文網:http://Nodejs.cn/

  Nodejs 系統模塊是什么 :隨着 Nodejs 一起安裝,並由官方進行維護的模塊。

    常用的系統模塊: fs、http、url、path 等一個模塊中包含了很多方法和屬性,可以幫助我們實現不同的功能

 

Node 創建 web 服務器

 

使用 HTTP 模塊搭建 web 服務器:

 

  1、引入 http 模塊

  創建一個 js 文件,例如此處取名為 kiss.js 。

 

const http = require('http');

 

  2、創建服務器對象

 

const server = http.createServer();

 

  3、開啟服務器

  此處監聽了 3000 端口

 

server.listen(3000, () => {
    console.log('Server is running...');
});

 

  4、監聽瀏覽器請求並進行處理

 

server.on('request', (req, res) => {
    // end方法能夠將數據返回給瀏覽器,瀏覽器會顯示該字符串
    res.end('Hello Nodejs');
});

 

  on :該方法用來監聽事件

  參數1(此處的request):事件類型,request 代表瀏覽器請求事件

  參數2 :回調函數。當監聽到瀏覽器請求后出發的回調函數,該函數中有兩個參數

      第一個參數(此處的 req ):請求對象

      第二個參數(此處的 res ):相應對象

  end 方法能夠將數據返回給瀏覽器,瀏覽器會顯示該字符串

  遂,在 kiss.js 文件中,內容如下:

 

//1. 導入 http 模塊
const http = require('http');

//2. 創建服務器對象
const server = http.createServer();

//3. 開啟服務器
server.listen(3000, () => {
    console.log('Server is running...');
});

//4. 監聽瀏覽器請求並進行處理
server.on('request', (req, res) => {
    // end方法能夠將數據返回給瀏覽器,瀏覽器會顯示該字符串
    res.end('Hello Nodejs');
});

 

  在文件目錄中打開 cmd ,運行命令 node .\kiss.js ,即可開啟服務器:

 

  打開瀏覽器,在地址欄輸入  http://127.0.0.1:3000/ ,會看到 res.end() 所返回的字符串

  如圖

 

  

 

顯示頁面

 

  服務器已經搭建起來了,那么下一步就是如何在瀏覽器端展示頁面了

  首先准備一個 HTML 文件,在 kiss.js 文件同級目錄下創建一個 index.html 文件,准備內容如下

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>kisskiss</title>
    <style>
        h2 {
            width: 800px;
            height: 60px;
            margin: 100px auto;
            line-height: 60px;
            text-align: center;
            color: white;
            background-image: linear-gradient(to right,
                      rgb(255, 211, 218) 0%,
                      rgb(132, 223, 132) 100%)
        }
    </style>
</head>
<body>
   <h2>我是 kiss 首頁</h2> 
</body>
</html>

 

  此時服務器文件 kiss.js 需要另一個模塊 :文件讀取模塊 ——> readFile

  1、引入 fs 模塊

 

const fs = require('fs');

 

  2、調用 readFile 方法讀取文件內容

 

fs.readFile('./index.html', 'utf-8', (err, data) => {
    if (err) {
        return console.log(err);
    }
    
    console.log(data);
})

 

  參數1 : 要讀取的文件路徑,相對路徑和絕對路徑均可(推薦使用絕對路徑)

  參數2 : 設置字符集, 常用的中文字符集有三種 : utf-8、 gb2312、 gbk 該參數是可選參數,如果不設置該參數,讀取內容默認是二進制數據

  參數3 : 讀取完成后觸發的回調函數,該函數中有兩個參數  err 和 data

    err : 錯誤對象 - 如果讀取正確 :  err 為 null ;  如果讀取失敗 :  err 為錯誤對象 ;

    data : 文件中的數據

  在 congsole.log(data) 處,便可進行對文件內容的操作,data 整個是以字符串類型被取出

   調整后 kiss.js 文件內容如下 :

 

const http = require('http'); //1. 導入 http 模塊
const fs = require('fs'); //5. 導入/加載/引入 文件模塊

//2. 創建服務器對象
const server = http.createServer();

//3. 開啟服務器
server.listen(3000, () => {
    console.log('Server is running...');
});

//4. 監聽瀏覽器請求並進行處理
server.on('request', (req, res) => {

    //6. 讀取文件
    fs.readFile('./index.html', 'utf-8', (err, data) => {
        if (err) {
            return console.log(err);
        }
        //7. end方法返回讀取的文件字符串,瀏覽器會顯示該文件內容
        res.end(data);
    })
    
});

 

  在 cmd 中 Ctrl + C 退出之前啟動的服務器,重新啟動服務器   node kiss.js 

  在瀏覽器中刷新頁面 http://127.0.0.1:3000/ ,可以看到准備的 HTML 頁面已經成功展示在瀏覽器中

  如圖

 

  

 

  Tips : 中文亂碼問題

  fs 的 readFile 函數中第二個參數可不寫,但是會造成頁面中文亂碼,另一個解決辦法是,使用 res(響應對象)中的 setHeader 方法:

 

res.setHeader('content-type', 'text/html;charset=utf-8');

 

 多個頁面時

 

  再新建一個HTML頁面,index_2.html 內容如下 :

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>第二個頁面</title>
    <style>
        i {
            display: block;
            background-color: pink;
            width: 300px;
            height: 50px;
            border-radius: 15px;
            text-align: center;
            line-height: 50px;
        }
    </style>
</head>
<body>
    <i>這是第二個頁面</i>
</body>
</html>

 

  此時問題是,如何才能在輸入不同的網址的時候,顯示不同的兩個頁面?

  解決辦法,修改 kiss.js 代碼如下 :

 

const http = require('http'); //1. 導入 http 模塊
const fs = require('fs'); //5. 導入/加載/引入 文件模塊

//2. 創建服務器對象
const server = http.createServer();

//3. 開啟服務器
server.listen(3000, () => {
    console.log('Server is running...');
});

//4. 監聽瀏覽器請求並進行處理
server.on('request', (req, res) => {
    //6. req對象的url屬性中保存了當前請求的url地址
    const url = req.url
    //7.判斷不同url,返回不同頁面到瀏覽器端進行展示
    if (url === '/') {
        //8. 讀取文件index.html
        fs.readFile('./index.html', 'utf-8', (err, data) => {
            if (err) {
                return console.log(err);
            }
            // end方法返回讀取的文件字符串,瀏覽器會顯示該文件內容
            res.end(data);
        })
    } else if (url === '/index_2') {
        //8. 讀取文件index_2.html
        fs.readFile('./index_2.html', 'utf-8', (err, data) => {
            if (err) {
                return console.log(err);
            }
            // end方法返回讀取的文件字符串,瀏覽器會顯示該文件內容
            res.end(data);
        })
    }
});

 

  重啟服務器,在瀏覽器地址欄輸入 http://127.0.0.1:3000 ,依舊顯示原來 index.html 頁面的內容

  在地址欄輸入 http://127.0.0.1:3000/index_2 ,顯示新的 index_2.html 頁面的內容,如下 :

 

  

  

  核心:req(請求對象)中有url屬性,該屬性中保存了當前請求的url地址

  注意: url屬性中保存的地址是沒有 協議、IP、端口號,並且以 / 開頭的地址

  

  示例:

  http://127.0.0.1:3000     ===>    /

  http://127.0.0.1:3000/index_2    ===>     /index_2

 

靜態資源加載

 

  上面已經初步體驗了一個服務器是怎樣跑起來的,但是!上面只有一個 html 文件,並且它的樣式是直接包含在 html 文件中的,如果一個 HTML 文件內引入了它的資源文件呢? 比如 css 和 js 文件。

  修改文件結構目錄如下 :

 

  

 

  index.html 頁面內容 :

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>kisskiss</title>
    <link rel="stylesheet" type="text/css" href="../public/css/index.css">
    <script type="text/javascript" src="../public/js/index.js"></script>
</head>
<body>
   <h2>我是 kiss 首頁</h2> 
</body>
</html>

 

  將原來 HTML 文件中的 css 資源單獨抽取出來寫入 index.css 文件中,index.css 文件內容 :

 

h2 {
    width: 800px;
    height: 60px;
    margin: 100px auto;
    line-height: 60px;
    text-align: center;
    color: white;
    background-image: linear-gradient(to right,
              rgb(255, 211, 218) 0%,
              rgb(132, 223, 132) 100%)
}

 

  index.js 文件內容 :

 

alert('this is kiss.js');

 

  kiss.js 文件內容 :

 

const http = require('http'); //1. 導入 http 模塊
const fs = require('fs'); //5. 導入/加載/引入 文件模塊

//2. 創建服務器對象
const server = http.createServer();

//3. 開啟服務器
server.listen(3000, () => {
    console.log('Server is running...');
});

//4. 監聽瀏覽器請求並進行處理
server.on('request', (req, res) => {
    //6. req對象的url屬性中保存了當前請求的url地址
    const url = req.url
    //7.判斷不同url,返回不同頁面到瀏覽器端進行展示
    if (url === '/') {
        //8. 讀取文件index.html
        fs.readFile('./view/index.html', 'utf-8', (err, data) => {
            if (err) {
                return console.log(err);
            }
            // end方法返回讀取的文件字符串,瀏覽器會顯示該文件內容
            res.end(data);
        })
    }
});

 

  啟動服務器,主頁一直處於加載狀態

  按下鍵盤 f12 ,或者單擊鼠標右鍵 → 檢查 → 選擇 network :

 

  

 

  可以看到 index.css 和 index.js 文件的狀態(status)顯示為 pending 

  服務器發起了對 index.css 和 index.js 文件的請求,但是卻一直未得到服務器的響應

  來分析一下此處的原理 :

 

  

 

  1、瀏覽器中輸入請求地址 http:127.0.0.1:3000,按下回車發送請求

  2、服務器根據請求信息的 url (此時為 "/")找到 index.html ,並將內容返回給瀏覽器

  3、瀏覽器接收到服務器返回的內容,開始對 index.html 進行解析,當解析到 link 標簽和 script 標簽時,再次請求服務器,想要獲取 index.css 和 index.js 文件,可是我們的服務器代碼中,並沒有寫針對這兩個文件的內容,所以也就不會返回這兩個文件的內容,服務器就會一直處於等待狀態,直到超時報錯。

  接下來我們修改一下 kiss.js 文件,內容如下 :

 

const http = require('http'); //1. 導入 http 模塊
const fs = require('fs'); //5. 導入/加載/引入 文件模塊

//2. 創建服務器對象
const server = http.createServer();

//3. 開啟服務器
server.listen(3000, () => {
    console.log('Server is running...');
});

//4. 監聽瀏覽器請求並進行處理
server.on('request', (req, res) => {
    //6. req對象的url屬性中保存了當前請求的url地址
    const url = req.url
    //7.判斷不同url,返回不同頁面到瀏覽器端進行展示
    if (url === '/') {
        //8. 讀取文件index.html
        fs.readFile('./view/index.html', 'utf-8', (err, data) => {
            if (err) {
                return console.log(err);
            }
            // end方法返回讀取的文件字符串,瀏覽器會顯示該文件內容
            res.end(data);
        })
    } else if (url === '/index_2') {
        //8. 讀取文件index_2.html
        fs.readFile('./view/index_2.html', 'utf-8', (err, data) => {
            if (err) {
                return console.log(err);
            }
            // end方法返回讀取的文件字符串,瀏覽器會顯示該文件內容
            res.end(data);
        })
    } else if(url.startsWith('/public')) {
        //8. 讀取index.html文件的靜態資源文件
        fs.readFile('.'+url, 'utf-8', (err, data) => {
            if (err) {
                return console.log(err);
            }
            // end方法返回讀取的文件字符串,瀏覽器會顯示該文件內容
            res.end(data);
        })
    }
});

 

  分析 :因為靜態資源文件全部被放到了同一個 public 文件夾下,所以我們用一個 else if 分支來處理就可以了

    index.css 文件的 req(請求對象)的 url 屬性,值為 '/public/css/index.css'

    index.js 文件的 req(請求對象)的 url 屬性,值為 '/public/js/index.js'

    所以我們判斷,當 url 以 '/public' 開頭的時候,便將 fs 的 readFile 方法的第一個參數(文件路徑)拼接成相對路徑加上 url 的形式

 

   刷新頁面,可以看到彈出 js 文件內容:

 

  

 

  點擊確定后可以看到帶有 css 樣式的頁面,成功顯示!

 

 

 

 

 

         

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM