Node.js快速入門——實現一個服務器

Node.js的出現讓前端工程師能夠服務端爭得一席之地,除了服務端以外Node.js在中臺也佔據着重要的地位,能夠說Node.js是前端人進階路上必備的技能之一了。而前端工程師學習Node.js成本很低,語法就是js的語法,只須要熟悉一下Node.js的API便可輕鬆上手。css

推薦閱讀路線

前言

Node.js是一個基於 Chrome V8 引擎的 JavaScript 運行環境。大白話說Node.js就是一個軟件,他能夠運行js/ts文件,使電腦充當一臺服務器。html

Node.js實現一臺服務器至少須要實現如下功能:前端

  • 響應靜態資源請求
  • 根據不一樣的請求url返回不一樣的內容
  • 得到前端發送的get請求的參數
  • 得到前端發送的post請求的參數

Node.js的安裝十分容易,在官網下載安裝便可,安裝完成後在終端中用node -v測試是否完成安裝。以下圖所示即安裝成功。node

準備工做

建立一個static文件夾用來存放靜態資源,server.js用於寫服務器代碼。 git

1 響應靜態資源請求

客戶端第一次向服務器發起的請求index.html文件的請求就是靜態資源請求,全部的html、css、js等文件都屬於靜態資源。github

Node.js在響應靜態資源的請求上不一樣於其餘後端語言,如PHP,PHP自己不響應靜態資源,而是經過Apache處理靜態資源的響應,PHP只處理數據的請求,而Node.js則是既要處理靜態資源的請求又要處理數據的請求。數據庫

那麼咱們首實現用Node.js來響應靜態資源請求。

// 首先引入http,fs,path模塊
const http = require('http')
const fs = require('fs')
const path = require('path')

// 建立一個服務器
const server = http.createServer((req, res) => {
  // 請求地址以'/static'開頭的爲請求靜態資源
  if(req.url.startsWith('/static')) {
    // 經過請求url得到對應文件的路徑
    let pathStr = path.join(__dirname,req.url)
    // 讀取文件內容並返回
    fs.readFile(pathStr,{encoding: 'utf8'}, (err,fileContent) => {
      if(err) {
        // 設置響應狀態碼爲404
        res.writeHead(404)
        res.end('查找不到資源,請檢查您的url是否正確')
      } else {
        res.end(fileContent)
      }
    })
  }
})
// 啓動服務器並監聽3000端口,啓動成功後向控制檯寫入 服務器啓動成功!
server.listen(3000,() => {
  console.log('服務器啓動成功!') 
})
複製代碼

接着在終端中先進入server.js文件所在路徑,而後使用node+文件名來運行js文件。express

在瀏覽器按照資源所在路徑訪問靜態資源,測試是否能正確返回靜態資源。
思路也是很是簡單,首先經過請求的url拼接出文件的絕對路徑,而後將文件內容讀取出來並返回客戶端便可,有了思路以後只須要記一下API就能夠了。

2 根據不一樣的請求url返回不一樣的內容

咱們剛剛只處理了靜態資源的請求,如今訪問其餘路徑不會有任何反應,由於咱們尚未對其餘請求url作處理。後端

接下來咱們作一個登錄註冊功能,分別處理/login、/register路徑,並對未處理的url返回404。瀏覽器

const server = http.createServer((req, res) => {
  // 請求地址以'/static'開頭的爲請求靜態資源
  if(req.url.startsWith('/static')) {
    // 經過請求url得到對應文件的路徑
    let pathStr = path.join(__dirname,req.url)
    fs.readFile(pathStr,{encoding: 'utf8'}, (err,fileContent) => {
      if(err) {
        res.writeHead(404)
        res.end('查找不到資源,請檢查您的url是否正確')
      } else {
        res.end(fileContent)
      }
    })
  } else if (/(^\/login$)|(^\/login\?.*$)/ig.test(req.url)) {
    // 匹配/login或者/login?xxx的url
    res.end('login')
  } else if(/(^\/register$)|(^\/register\?.*$)/ig.test(req.url)) {
    // 匹配/register或者/register?xxx的url
    res.end('register')
  } else {
    // 未處理的url返回404
    res.writeHead(404)
    res.end()
  }
})
複製代碼

訪問 localhost:3000/login或localhost:3000/login?xxxx時能夠看到返回了數據。

而訪問未處理的url時則報404錯誤。

3 得到前端發送的get請求的參數

首先咱們在index.html中建立一個表單,用於提交登錄信息,信息提交到/login,方式爲GET

<form action='/login' method='GET'>
    <label>
        用戶名:
        <input type='text' name='username' placeholder='請輸入用戶名'/>
    </label>
    <br>
    <label>
        密碼:
        <input type="password" name='password' placeholder='請輸入密碼' />
    </label>
    <br>
    <input type='submit' value='提交'>
</form>
複製代碼

接下來解析GET請求參數須要用到url模塊,先引入

const url = require('url')
複製代碼

而後對匹配/login的規則進行修改

else if (/(^\/login$)|(^\/login\?.*$)/ig.test(req.url)) {
    // 匹配/login或者/login?xxx的url
    // 設置響應數據類型
    res.setHeader('Content-Type','text/plain;charset=utf8')
    // 判斷請求是否爲GET
    if (req.method === 'GET') {
      // 得到參數
      const params = url.parse(req.url, true).query
      // 僞裝讀取了數據庫,用戶名爲admin,密碼爲123則登錄成功
      if(params.username === 'admin' && params.password === '123') {
        res.end('登陸成功!')
      } else {
        res.end('您的帳號或密碼有誤,請重試')
      }
    }
    res.end('login')
}
複製代碼

4 得到前端發送的post請求的參數

將index.html中的表格提交方式改成POST請求

<form action='/login' method='POST'>
複製代碼

接下來解析POST請求參數須要用到querystring模塊,先引入

const querystring = require('querystring')
複製代碼

而後繼續對匹配/login的規則進行修改

post請求的參數是放在http請求體中的,Node.js接收http請求體的數據是採用事件監聽的方式接收的,收到一部分http請求體的數據會觸發一次data事件,所有接收完會觸發end事件,咱們先接收全部數據而後對數據格式化提取出咱們想要的參數

else if (/(^\/login$)|(^\/login\?.*$)/ig.test(req.url)) {
    // 匹配/login或者/login?xxx的url
    // 設置響應數據類型
    res.setHeader('Content-Type','text/plain;charset=utf8')
    // 判斷請求是否爲GET
    if (req.method === 'GET') {
      // 得到GET參數
      const params = url.parse(req.url, true).query
      // 僞裝讀取了數據庫,用戶名爲admin,密碼爲123則登錄成功
      if(params.username === 'admin' && params.password === '123') {
        res.end('登陸成功!')
      } else {
        res.end('您的帳號或密碼有誤,請重試')
      }
    } else if (req.method === 'POST') {
      // 得到POST參數
      let paramsStr = ''
      req.on('data', thunk=> {
        // thunk爲http請求體中的一部分數據
        paramsStr += thunk
      })
      // 所有接收完觸發end事件
      req.on('end', () => {
        const params = querystring.parse(paramsStr)
        // 僞裝讀取了數據庫,用戶名爲admin,密碼爲123則登錄成功
        if(params.username === 'admin' && params.password === '123') {
          res.end('登陸成功!')
        } else {
          res.end('您的帳號或密碼有誤,請重試')
        }
      })
    }
}
複製代碼

再次在index.html中登陸

此時的參數存放在http的請求體中

5 交流

若是這篇文章幫到你了,以爲不錯的話來點個Star吧。 github.com/lizijie123

相關文章
相關標籤/搜索