Express 的基本使用,前端進階 Node 的第一課

Node 的應用及知識點

在前端平時的工作中,對後端的瞭解比較少,但是應該都知道 Node 可以用於寫後端,今天這篇文章來介紹一下 Node 的知名框架 Express 的基本使用,從應用起步,去學習 Node

先來了解一下 Node 可以做什麼,再決定需不需要學習,從兩個點出發,首先是應用場景:

  • 代理服務(用於解決跨域)
  • 中間層(用於數據二次處理、流量攔截)
  • Webpack(用於對文件內容進行二次處理)
  • 服務端渲染(這個都懂)

其次是可以學到什麼知識:

  • 對後端的基礎入門,成爲一個懂後端的前端;
  • 對數據傳輸的進一步瞭解,深入 HTTP 和 TCP;
  • 一些簡易腳本的編寫,學會自動化(偷懶);

如果對這些優點感興趣的話,我們的學習將從下面這個例子開始,學會基礎的 路由選擇響應數據請求,然後我們將完成一個可供交互的 接口(對,就是工作中前後端聯調的那種接口),最後我們使用 Node 來解決經典的 跨域問題

案例展示:路由選擇

我們在這個案例中畫出四朵金花,然後通過不同的路由訪問不同狀態的金花。


如果你的電腦還沒有安裝 Node,那麼你需要安裝一下 Node。我們進入一個全新的目錄,使用 npm init 來初始化項目,這一步可以一直按回車鍵結束,你也可以自己自定義一些選項。然後我們使用 npm install express --save 來安裝 express,依賴安裝完成後,我們在當前文件夾新建一個 app.js,準備開始鍵入我們的內容。

我們在 app.js 中寫入以下代碼:

const express = require("express");

const app = express();

app.get("/", (req, res) => {
  res.end("Hello Express");
});

app.listen(8888, () => {
  console.log("server is listening in http://localhost:8888")
})

在運行代碼之前,我們先來簡單的解析一下代碼:

  • const app = express();:新建一個 express 實例,實例包含了 express 的屬性;
  • app.get("/", callback)express 的路由控制,在客戶端訪問該路由時,將會執行傳入的回調函數;
  • res.end("Hello Express"):響應一個 Hello Express 字符串;
  • app.listen(8888, callback):進程運行在 8888 端口上,監聽該端口的請求;

所有細節都解析完了,接下來我們使用 node app.js 來運行我們的程序:

Tips: 安裝 nodemon 的話(npm install nodemon -g),你可以使用 nodemon app.js 來運行程序,nodemon 會持續監聽文件的變動而重啓服務,更適合開發階段使用。

控制檯會輸出一條信息 server is listening in http://localhost:8888,此時我們打開瀏覽器,輸入 http://localhost:8888,就可以看到我們的服務響應了一條消息:

響應結果

我們是怎麼做到的,是通過 app.get("/", callback) 執行的回調函數返回的結果,那回調函數參數中的 reqres 又是什麼呢?本文不作深入講解,有興趣的童鞋可以看看這篇 手把手教你用 Node 實現 HTTP 協議 這裏面對 reqres 的實現介紹的比較仔細,看完對 HTTP 協議的掌握也能更上一層樓。

即使不瞭解這些細節,我們也可以繼續往下講,你只需要把 res.end() 簡單理解爲一個向客戶端發送數據的 API 即可。根據這個特點,我們就知道我們的四大金花要怎麼做了,我們需要先定義四個路由,然後每個路由執行不同的回調函數,返回對應的金花即可。

Tips:點擊下載四大金花源碼,將源碼下載後放置在文件夾的 static 目錄下即可。

目錄截圖

const app = express() 下加一行代碼,將我們的 static 目錄變成一個靜態文件目錄,這樣可以保證我們的 jscss 文件能夠被正確加載,加上了 express.static 就提供了文件服務器功能,將你的 html 文件放在 static 目錄中就可以通過路徑進行訪問了!

//...

// 使用 /static 路徑作爲我們的靜態文件路由,static 作爲我們的靜態文件目錄
app.use('/static', express.static('static'));

我們接下來只需要在訪問路由時,將 html 文件作爲相應返回給客戶端即可,實際代碼如下:

const express = require("express");
const path = require("path");

const app = express();

app.use('/static', express.static('static'));

app.get("/", (req, res) => {
  res.end("Hello Express");
});

// 新增了四個路由,用於訪問不同狀態的金花
app.get("/happy", (req, res) => {
  // res.SendFile 響應一個本地文件
  // path.join 用於拼接一個路徑
  // __dirname 是當前文件夾路徑,屬於 Node 的一個全局變量
  res.sendFile(path.join(__dirname, "./static/happy.html"))
})

app.get("/crazy", (req, res) => {
  res.sendFile(path.join(__dirname, "./static/crazy.html"))
})

app.get("/sexy", (req, res) => {
  res.sendFile(path.join(__dirname, "./static/sexy.html"))
})

app.get("/cool", (req, res) => {
  res.sendFile(path.join(__dirname, "./static/cool.html"))
})

app.listen(8888, () => {
  console.log("server is listening in http://localhost:8888")
})

重啓一下服務,打開瀏覽器,分別輸入以下四個地址,就可以看到不同狀態的四朵小花了,趕緊試試吧!

  • http://localhost:8888/happy
  • http://localhost:8888/crazy
  • http://localhost:8888/sexy
  • http://localhost:8888/cool

案例展示:API 接口

接下來我們來實現一個 API 接口,它可以分頁查詢查詢數據,還可以根據篩選條件返回對應的查詢結果,就是我們平時和後端聯調的那種“接口”,我們將在表現上保持一致。

首先我們使用 npm install axios -s 安裝 axios 用於請求第三方鏈接,第三方數據將成爲我們的數據來源。安裝完成後,我們引入 axios,並且添加一個路由,用於返回接口數據,我們這麼定義它:

// 新增路由 /product/list
app.get("/product/list", (req, res) => {
  // 使用 axios 獲取 http://dev-api.jt-gmall.com/mall 的數據
  axios.post("http://dev-api.jt-gmall.com/mall", {
    query: `
    { counterGoodsList (page: 1, pageSize: 10) 
      { 
        total 
        page 
        pageSize 
        items {
          _id
          name
          price
        }
      } 
    }`
  }).then(({ data }) => {
    // 等待請求結果的返回
    // 設置響應頭
    res.setHeader("Content-Type", "application/json")

    // 響應一個 JSON 字符串,將獲取到的數據進行 JSON 序列化
    res.end(JSON.stringify(data));
  });
});

我們使用 Postman 來調試我們新寫的這個接口看看可不可行,實際結果如下:

請求結果

很好,我們已經成功了一半,接下來我們需要對入參進行篩選,我們在這裏就實現最簡單的一個分頁功能,我們希望通過 url query 參數來進行分頁查詢,我們需要先處理客戶端傳入的 page 相關參數,然後再將這些參數進行對應的處理後告知數據源(第三方或數據庫),最後將響應的數據返回即可,那麼改動後的代碼如下:

app.get("/product/list", (req, res) => {
  const page = req.query.page || 1;
  const pageSize = req.query.pageSize || 10;
  axios.post("http://dev-api.jt-gmall.com/mall", {
    query: `
    { counterGoodsList (page: ${page}, pageSize: ${pageSize}) 
      { 
        total 
        page 
        pageSize 
        items {
          _id
          name
          price
        }
      } 
    }`
  }).then(({ data }) => {
    res.setHeader("Content-Type", "application/json")
    res.end(JSON.stringify(data))
  });
});

然後我們就可以通過自定義參數來請求,我們請求第二頁的數據,並且將每頁數量設置爲 20,響應結果如下:

響應結果

這就是 Node 的中間層功能,而我們只需要加一行代碼,就可以解決跨域問題。

案例展示:解決跨域問題

如果你嘗試在 Web 網頁中使用 Ajax 訪問 http://dev-api.jt-gmall.com/mall,那麼你肯定會遇到跨域問題,因爲這個域名並不允許你使用瀏覽器直接訪問,但是從上一個案例中,我們可以通過訪問 http://localhost:8888/product/list 來取得同樣的數據。

跨域是瀏覽器的一個安全策略,而 Node 在訪問其他鏈接時是一個非瀏覽器客戶端,並不會遇到跨域的問題。那我們可以在瀏覽器使用 Ajax 訪問 http://localhost:8888/product/list 嗎?嘗試過後,你會發現依然會遭遇跨域問題。

其實我們深究跨域問題的話,跨域就是瀏覽器實現的一個安全策略,它要求服務器響應頭必須包含幾個 CORS 相關的響應頭,來確保請求是被允許的。根據這個原理,我們只需要在每個響應的頭部加上這些 CORS 相關信息即可。有個插件可以幫我們做這些事情,那就是 cors,我們運行 npm install cors --save 來安裝它。

我們加入兩行代碼就可以解決客戶端的跨域問題了,代碼如下:

const cors = require("cors");

app.use(cors());

結語

我們使用了三個簡單的案例介紹了 Express 的基本使用,算是一個入門吧。如果希望深入學習的話,最好是參照 ExpressNode 的官方文檔,跟着案例一行一行敲下來最好。

如果有什麼問題的話,歡迎留言喲!

會跳舞的小花 源碼地址

原文地址,歡迎收藏

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章