express 入門

基礎的 express 實現(xiàn)靜態(tài)文件訪問

index.js 開啟 http 服務

const express = require('express'); // 引入 express 模塊
const globalConfig = require('./config');  // 導入全局配置
const app = new express();  // 實例化一個 express

app.use(express.static(globalConfig['page_path'])); // 告訴 express 示例, 靜態(tài)文件的位置

app.listen(globalConfig['port']); // 監(jiān)聽配置文件中的端口

server.conf是服務的配置文件

port=8081
page_path=page

config.js 用來處理 server.conf ,將配置文件轉換為配置對象

/*
將配置文件格式化成對象鍵值對的形式
 */

const fs = require('fs');  // 引入 fs 模塊

let globalConfig = {}; // 定義全局配置對象

let conf = fs.readFileSync('./server.conf'); // 同步讀取 server.conf 文件

let confArr = conf.toString().split("\n"); // 通過回車符拆分

for (let i = 0, len = confArr.length; i < len; i++) {
  globalConfig[confArr[i].split('=')[0]] = confArr[i].split('=')[1]
}

module.exports = globalConfig; // 將配置對象導出

page 文件夾中存放頁面文件

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
  <h1>Hello, world!</h1>
</body>
</html>

然后運行 index.js,瀏覽器訪問127.0.0.1:8081

基于 express 搭建 web 服務

這個不同于上面簡單的web服務,這是一個完整的簡易 web 服務。
首先目錄是這樣的:


server.conf

盡管它不在一個文件夾中, 也是很重要的一環(huán)
這個文件定義了整個服務的基本信息。

port=8081
page_path=page
web_path=web

盡管只有簡單的三行, 但是業(yè)務邏輯復雜之后, 這個文件也會逐漸豐滿的。如果不定義此文件,在需要這些字段的時候,就會變得很麻煩。例如改端口號, 可能很多地方都需要改, 但是有這個文件, 只需要修改文件中的端口就好了。

config.js

有了配置文件, 肯定需要一段代碼去解析配置文件。

/*
將配置文件格式化成對象鍵值對的形式
 */
const fs = require('fs');  // 引入 fs 模塊
let globalConfig = {}; // 定義全局配置對象
let conf = fs.readFileSync('./server.conf'); // 同步讀取 server.conf 文件
let confArr = conf.toString().split("\n"); // 通過回車符拆分
for (let i = 0, len = confArr.length; i < len; i++) {
  globalConfig[confArr[i].split('=')[0]] = confArr[i].split('=')[1]
}
module.exports = globalConfig; // 將配置對象導出

這個文件的目的是將上面的配置文件格式化為對象的形式:

{ 
  port: '8081',
  page_path: 'page',
  web_path: 'web',
  '': undefined
}

然后在需要配置項的地方使用globalConfig.xxx的形式即可。

index.js

此文件用于創(chuàng)建服務。

const express = require('express'); // 引入 express 模塊
const globalConfig = require('./config');  // 導入全局配置
const app = new express();  // 實例化一個 express
const loader = require('./loader')
app.use(express.static(globalConfig['page_path'])); // 告訴 express , 靜態(tài)文件的位置
app.post("/dosomething", loader.get("/dosomething")) // 請求數(shù)據(jù)的方法
app.listen(globalConfig['port']); // 監(jiān)聽配置文件中的端口

app.post("/dosomething", loader.get("/dosomething")):
假設點擊了一個按鈕, 這個按鈕要獲取數(shù)據(jù)。這個請求可能是www.example.com/dosomething?name=xx&age=yy, 然后服務監(jiān)聽到這個請求, 然后就會去loader.js中尋找對應的處理函數(shù), 對這個請求進行處理。至于參數(shù)在哪里, 這個請求是怎么處理的, 在下面會介紹。

這個時候服務已經(jīng)搭好, 已經(jīng)可以訪問靜態(tài)文件了。

page

page 文件夾之下都是靜態(tài)資源信息。如果請求為靜態(tài)資源, 會直接去express.static參數(shù)的文件夾下尋找。

web

如果說 page 文件夾存放靜態(tài)資源, 那么 web 的作用就是存儲獲取動態(tài)數(shù)據(jù)的方法。
在這里, 有許多的 controller,是用來處理邏輯的。這里有一個dosomething的例子:

const timeUtil = require('../Utils/timeUtil')
const writeRes = require('../Utils/resultUtil')
let path = new Map()
let dosomething = require('../dao/somethingDao');
function something(request, response) {
  request.on('data', function (data) {
    dosomething.dosomething(data, timeUtil.getNow(), function (res) {
      response.writeHead(200)
      response.write(writeRes.writeResult("success OK", timeUtil.getNow(), res))
      response.end()
    })
  })
}
path.set("/dosomething", something)
module.exports = path

請求的urlrequest里面。可以使用url模塊解析這個url獲取對應的參數(shù)信息。data就是post請求發(fā)送過來的參數(shù)。這里忽略了對 data 的解析。

loader.js

const fs = require('fs')
const globalConfig = require('./config')
let controllerSet = []
let pathMap = new Map()
let files = fs.readdirSync(globalConfig['web_path']) // 讀取文件夾
for (let i = 0, len = files.length; i < len; i++){ // 讀取 files 中所有的文件
  let temp = require('./' + globalConfig['web_path'] + '/' + files[i]) // 引入 web 里面的文件
  if(temp.path){
    for (let [key, value] of temp.path){ // 讀取 每一個文件的 path
      if(pathMap.get(key) == null){ // 如果在 pathMap 中沒有, 就添加進去
        pathMap.set(key, value)
      }else {                       // 如果進入 else , 說明 url 重了。 這當然不允許
        throw new Error("url error, url: " + key);
      }
      controllerSet.push(temp)
    }
  }
}
module.exports = pathMap // 將 pathMap 導出

讀取上面的web文件夾, 引入所有的js文件, 引入一個解析一個, 獲取到所有的處理動態(tài)數(shù)據(jù)的方法, 將這些方法全部放入一個叫做pathMapMap中 ,然后將之導出, 在index.js里面引入pathMap。然后根據(jù)不同請求, getloader里面對應的方法。

dao(Data Access Object)

此文件夾下有兩類文件,第一類只有一個, 叫做DBUtil.js,它用于創(chuàng)建一個與數(shù)據(jù)庫的鏈接。

let mysql = require('mysql')
function createConnection() {
  return mysql.createConnection({
    host: "127.0.0.1",
    port: "3306",
    user: "root",
    password: "123546",
    database: "test"
  })
}
module.exports.createConnection = createConnection

第二類可能有很多個, 它們用于響應用戶請求對數(shù)據(jù)庫的增刪改查操作。
這里是上面dosomething的例子:

const DBUtil = require('./DBUtil')  // 引入創(chuàng)建數(shù)據(jù)庫的工具方法
function dosomething(content, ctime, success) {
  let sql = "insert into table (`content`, `ctime`) values (?, ?)" // 編寫數(shù)據(jù)庫查詢語句
  let params = [content, ctime]                   // 定義參數(shù)列表
  let connection = DBUtil.createConnection()      // 創(chuàng)建一個數(shù)據(jù)庫的鏈接
  connection.connect()                            // 連接
  connection.query(sql, params, function (err, result) {  // 進行查詢
    if (!err){      // 如果過程沒有出錯
      success(result)   
    } else {
      console.log(err)
    }
  })
  connection.end() // 查詢完畢一定要關閉數(shù)據(jù)庫的連接
}
module.exports.dosomething = dosomething // 將此方法導出,供 web 層使用

至此, 文件夾說明完畢。

回顧整個流程。
使用 express 開啟一個服務。
使用 app.get, app.post 等待對應的請求進來。
請求進來之后, 使用loader.get()拿到對應的處理方法。這個方法去查詢數(shù)據(jù)庫, 邏輯復雜的還要經(jīng)過邏輯處理流程, 查詢完畢之后執(zhí)行loader預先設置到的回調函數(shù), 這個回調函數(shù)返回給客戶端需要的數(shù)據(jù)。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容