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)
執行的回調函數返回的結果,那回調函數參數中的 req
和 res
又是什麼呢?本文不作深入講解,有興趣的童鞋可以看看這篇 手把手教你用 Node 實現 HTTP 協議 這裏面對 req
和 res
的實現介紹的比較仔細,看完對 HTTP
協議的掌握也能更上一層樓。
即使不瞭解這些細節,我們也可以繼續往下講,你只需要把 res.end()
簡單理解爲一個向客戶端發送數據的 API
即可。根據這個特點,我們就知道我們的四大金花要怎麼做了,我們需要先定義四個路由,然後每個路由執行不同的回調函數,返回對應的金花即可。
Tips:點擊下載四大金花源碼,將源碼下載後放置在文件夾的
static
目錄下即可。
在 const app = express()
下加一行代碼,將我們的 static
目錄變成一個靜態文件目錄,這樣可以保證我們的 js
和 css
文件能夠被正確加載,加上了 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
的基本使用,算是一個入門吧。如果希望深入學習的話,最好是參照 Express
和 Node
的官方文檔,跟着案例一行一行敲下來最好。
如果有什麼問題的話,歡迎留言喲!