JavaScript >> Javascript 文檔 >  >> Node.js

Node.js Express 示例:渲染、REST 和靜態網站

自 90 年代末 WWW 熱潮以來,Web 開發已經走過了漫長的道路。作為開發人員,我們現在擁有無限的資源和工具可供使用。我們擁有的絕對多功能性令人驚嘆。

隨著 Node.js 和 npm 的興起,JavaScript 已成為世界上事實上使用最多的編程語言。就像每天都會彈出一個新框架一樣。很煩人,我知道。但是,讓我們開始炒作,看看如何使用 Node.js 構建很酷的東西。如果你還沒有嘗試過,你一定會愛上它的,我敢肯定!

今天我們將使用最流行的 Node.js 框架 Express.js 創建四種不同類型的應用程序。

在我們開始之前,我們需要了解一些關於 Node.js 和 Express 的事情,以便弄清楚我們的方向。

把你的腳弄濕

Node 是基於 Chrome 的 V8 JavaScript 引擎構建的異步事件驅動的 JavaScript 運行時。它旨在構建可擴展的網絡應用程序。 JavaScript 是單線程的,所以 Node 的優勢在於它的異步特性。它在不阻塞執行主線程的情況下處理事件。這就是 Node 速度非常快的原因,因為它可以同時處理連接。

Node.js 爆發並變得像今天這樣流行的真正原因是包管理器隨之而來。 NPM 是所有 Node 包的主要聚會場所,因此得名。節點包管理器,嗯?在這裡您可以找到各種代碼模塊以在您的應用程序中使用,或者如果您願意,也可以發布您自己的代碼模塊。

其中一個模塊是 Express.js,這是一個非常流行的極簡 Web 框架,用於快速構建 Node.js 應用程序。 Express 是當今用於 Node.js 的事實上的主要框架。確實有很多理由。它只提供了一個薄薄的基礎抽象層,而不改變 Node 著名的核心特性。它可以輕鬆創建 Web 應用程序和 REST API,幾乎沒有任何麻煩。事實上,很多其他框架都是基於 Express 的!

現在您想知道您甚至可以使用 Express 構建什麼樣的應用程序?讓我們花點時間談談。 Web 支持的主要類型有哪些?有些應用程序帶有服務器呈現的 HTML 頁面,你們中的一些老派程序員會很熟悉。在 JavaScript 炒作之前,這是創建應用程序的默認方式。

然後我們有 REST API。它們通常用於發送和接收 JSON 有效負載,通常是與數據庫或其他服務之間的往來。

最後,我們有簡單的靜態網站。在這種情況下,Express 用於啟動服務器並提供這些文件。這是為公司和初創企業創建登錄頁面或營銷頁面的快速方法。

頭部先跳

到目前為止,邊做邊學是學習任何新事物的最佳原則,尤其是在編程方面。讓我們深入並解釋沿途的事情。

服務器渲染應用程序

你可以從標題猜到這些應用程序是如何工作的吧?在用戶瀏覽器中呈現的 HTML 頁面在服務器上生成和呈現。這個過程稱為服務器渲染。此類應用程序由模板引擎和模板組成。引擎生成要呈現的最終 HTML 頁面。一些流行的引擎包括 Jade、Pug 和 EJS。

這些引擎有什麼特別之處?他們有一個花哨的東西叫做插值。它可以將變量插入到模板或字符串中。像 Jade 的這個例子:Hello #{world} world 是一個變量。

讓我們來看看它的實際效果。

創建一個新目錄並打開一個終端窗口。在目錄下初始化npm,安裝以下模塊。

$ npm init
$ npm install --save express jade

這個項目的結構非常簡單。一個用於所有應用程序配置的 app.js 文件,一個用於啟動 http 服務器的 server.js 文件和一個用於存儲我們所有模板的視圖文件夾。首先,創建 app.js 文件並將這段代碼粘貼到其中。

// copy this into your app.js
const express = require('express');
const path = require('path');
const app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

app.get('/', function(req, res, next) {
    res.render('index', { title: 'Hello World!' });
});

module.exports = app;

好的,這是怎麼回事?我們需要 express 並實例化 app 目的。 path module 是一個內置的 Node 模塊,它提供了一種處理文件和目錄的方式。我們在這個例子中使用它來確保我們的文件路徑在所有平台上都能正常工作。

然後我們設置視圖引擎和我們的模板所在的文件夾。我們將在此示例中使用的視圖引擎將是 Jade,但這裡任何視圖引擎都可以。

現在是有趣的部分,請參閱 .get() 應用程序對像上的方法?它需要2個參數。首先是路由,然後是回調函數。當'/'路由被命中時,回調將被調用。這將觸發索引模板的渲染,其中包含一個名為 title 的插值變量 具有“Hello World!”的值。最後,我們導出應用程序以在其他文件中訪問它。

驚人的!解決這個問題,讓我們創建 server.js 文件並添加此代碼段。

const app = require('./app');
const port = 3030;

app.listen(port, function() {
    console.log('Express server listening on port ' + port);
});

這裡我們需要 app.js 文件並告訴它監聽 3030 端口。

還有一件事要做,用一些模板創建“views”文件夾。現在繼續添加“views”文件夾,然後放入這兩個模板。

<!-- layout.jade -->
doctype html
html
  head
    title= title
  body
    block content

<!-- index.jade -->
extends layout

block content
  h1= title
  p Welcome to #{title}

如您所見,與常規 HTML 相比,jade 模板引擎的語法非常怪異。但不要讓它愚弄你。最後,它將在瀏覽器中呈現為常規 HTML。看看有趣的 #{title} ?這就是我上面提到的插值。 title 回調函數中的變量被傳遞給視圖,呈現為提供的值。

示例應用的最終文件夾結構應如下所示。

> node_modules
> views
 - index.jade
 - layout.jade
- app.js
- package.json
- package-lock.json // this file will be present only if you have NPM version 5 or above.
- server.js 

如果您錯過了一些步驟,請查看 repo 以趕上進度。

呼,終於可以運行應用程序來看看它的樣子了。跳回你的終端並運行:

$ node server.js

您應該會看到“Express 服務器正在偵聽端口 3030”被登錄回您的終端。在您的瀏覽器中,轉到 http://localhost:3030,您應該會看到文本“Hello World!”和“歡迎來到 Hello World!”在屏幕上。

REST API

準備好讓你的世界天翻地覆了嗎?歡迎使用 REST API。首字母縮略詞代表 Re 表象 S 泰特 T 轉移。但你永遠不需要記住這一點。但重要的是要了解 REST 工作原理背後的邏輯以及為什麼它是首選的數據交付類型。

核心在於創建一個API,一個A 申請P rogram ninterface,以 JSON 格式發送和接收數據。 REST API 用於與數據庫交互以持久存儲數據。幸運的是,將 REST 與 Express 結合使用很容易。

讓我們來看看它的實際效果。

對於這個例子,我們只需要兩個模塊。 Express 和正文解析器。新建項目目錄並運行:

$ npm init && npm install --save express body-parser

我們只需要兩個文件就可以讓示例應用正常運行,所以繼續創建一個 app.js 和一個 server.js。

將這些片段複製到文件中。

'use strict';

//
// app.js
//

const express = require('express');
const app = express();
const bodyParser = require('body-parser');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.get('/', function(req, res) {
    let data = {
        message: 'Hello World!'
    };
    res.status(200).send(data);
});

app.post('/', function(req, res) {
    let data = {
        response: 'You sent: ' + req.body.message
    };

    // Do something, like query a database or save data

    res.status(200).send(data);
});

module.exports = app;
'use strict';

//
// server.js
//

const app = require('./app');
const port = 4040;

app.listen(port, function() {
    console.log('Express server listening on port ' + port);
});

app.js 的佈局與服務器渲染的示例非常相似。唯一真正的區別是我們返回一個 JSON 對像作為 get() 的響應 方法。讓我們分解一下。

在頂部,我們再次需要 express ,並創建一個 app 目的。但是,我們還需要 body-parser .這是一個很棒的 Express 中間件模塊,用於解析傳入的 HTTP 請求的正文。它將一個對象添加到 Express 的 req app 內的對象 方法。因此,當我們將一些數據發佈到 '/' 路由時,我們可以在 req.body 中訪問該數據 目的。太棒了!

免費電子書:Git Essentials

查看我們的 Git 學習實踐指南,其中包含最佳實踐、行業認可的標準以及隨附的備忘單。停止谷歌搜索 Git 命令並真正學習 它!

要對此進行測試,請啟動 Postman 之類的工具或您喜歡的任何其他 REST 客戶端測試工具。如果您以前從未聽說過,請不要驚慌,您可以在這裡查看..

啟動 server.js 並打開 Postman。

$ node server.js

在 Postman(或任何其他 REST 客戶端工具)中,首先向 http://localhost:4040/ 發送 GET 請求:

現在向同一個 url 發送一個 POST 請求:

在請求正文中輸入“消息”作為 JSON 數據(在本例中使用“x-www-form-urlencoded”)並點擊“發送”。您發送到端點的消息應該像這樣發送回給您:

{
    "response": "You sent: Hello World!"
}

切換回代碼,讓我們解釋發生了什麼。在 POST 路由中,我們從 req.body.message 中獲取值 並將其分配給 data 變量與我們自己的短消息。然後我們在響應中返回數據,狀態為 200。

此類請求僅用作向服務器傳輸數據或從服務器傳輸數據的方式,用於將數據存儲在數據庫等持久存儲中。這就是 REST API 的厲害之處。在當今世界,它們之所以蓬勃發展,是因為它們與移動和 Web 應用程序協同工作作為其數據存儲。

如果你錯過了任何步驟,你可以在這裡查看代碼。

靜態網站

如果我們不需要任何酷炫的模板渲染,也不需要與數據庫交互怎麼辦?如果我們只想要一個很酷的登錄頁面、一個很棒的概念證明頁面或一個靜態文件服務器怎麼辦?

讓我們忽略上面提到的所有復雜用例,並專注於萬維網所基於的基礎。提供 HTML 文檔。

Express 可以變成一個簡單的 HTTP Web 服務器,用於提供靜態 HTML 頁面。這個過程非常簡單。所需要的是指定一個將被視為靜態目錄的位置。

讓我們潛入。

創建一個新目錄,創建與上面示例相同的兩個文件,一個 app.js 和一個 server.js。您只需要為此示例安裝 express。

$ npm init && install express --save
// app.js
const express = require('express');
const app = express();

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

module.exports = app;

應用設置為 .use() 用於提供靜態文件的 html 文件夾。這意味著 url 中資源的路由不會在 Express 應用中查找路由,而是在文件系統中搜索請求的文件。

您可以簡單地重用上面示例中的 server.js。

// server.js
const app = require('./app');
const port = 5050;

app.listen(port, function() {
    console.log('Express server listening on port ' + port);
});

創建一個名為“html”的文件夾並添加兩個名為“index.html”和“about.html”的文件。文件的內容無關緊要,我只是添加了一些文本來知道哪個是哪個。

<!-- index.html -->
<h1>index</h1>

<!-- about.html -->
<h1>about</h1>

就這樣。繼續,啟動服務器並打開瀏覽器並前往 http://localhost:5050,它應該會顯示一個帶有“索引”字樣的頁面。

您可以通過請求 '/' 路由來查看 index.html 已默認加載。您可以切換到“/about.html”,然後將加載“about”HTML 文件。此原則適用於任何類型的文件。您也可以將圖像添加到此文件夾,如果您通過 URL 導航到它,它將以相同的方式顯示。

如果您錯過了任何步驟,請稍事休息並查看此處的代碼。

混合應用

不,我們不會去談論豐田普銳斯。這是另一種類型的混合動力車。假設您想要 REST API 的多功能性、強大性和易用性,同時還想要單頁應用程序 (SPA) 的速度。

快速信息:SPA 是前端 JavaScript 應用程序,只有一個主 index.html 文件。所有其他 html 文件都是在需要時注入到主文件中的模板。因為邏輯和路由是在前端處理的,所以速度非常快。但最終,在為它們提供服務時,它們的行為就像一個簡單的靜態網頁。

如果是這種情況,您可能會考慮這種情況。為什麼不在同一服務器上運行帶有靜態服務 SPA 的 REST API。聽起來不錯。

啟動終端,創建一個新目錄並輸入:

$ npm init && npm install --save express body-parser

我們來介紹一下文件夾結構。

> app       // folder that will hold all of our files for the SPA
> node_modules
- app.js
- package-lock.json
- package.json
- server.js

結構與靜態文件服務示例中的結構相同,只是我們將保存靜態文件的文件夾名稱不同。

這是一些代碼:

// app.js
const express = require('express');
const app = express();
const path = require('path');
const bodyParser = require('body-parser');

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));

/**
 * API
 */
app.get('/api', function(req, res, next) {
    let data = {
        message: 'Hello World!'
    };
    res.status(200).send(data);
});
app.post('/api', function(req, res, next) {
    let data = req.body;
    // query a database and save data
    res.status(200).send(data);
});

/**
 * STATIC FILES
 */
app.use('/', express.static('app'));

// Default every route except the above to serve the index.html
app.get('*', function(req, res) {
    res.sendFile(path.join(__dirname + '/app/index.html'));
});

module.exports = app;

這種結構現在看起來很熟悉不是嗎。我們將 REST API 與服務靜態文件結合在一起。唯一的例外是最後一個 .get() 在底部。 * 匹配除上述之外的所有路由將默認將 index.html 發送回客戶端。這意味著每條路線都將服務於主要的 index.html。正是我們想要的!

現在,當我們想從 API 中檢索一些數據時,我們可以簡單地點擊“/api”路由並取回 JSON 數據。否則,應用程序將始終提供位於應用程序文件夾中的主 HTML 文件。

如果您想了解更多細節,可以在此處查看使用 Angular.js 的完整示例。

什麼時候用什麼?

沒有任何應用程序類型在每種情況下都是最好的。他們都在編程世界中佔有一席之地。這完全取決於您的用例和您想要構建的內容。

如果您想要一個健壯的後端而不必過多擔心前端,那麼您會真正喜歡服務器渲染的應用程序。他們有很棒的模板引擎,可以簡化你編寫 HTML 的方式,讓創建複雜的模板變得非常容易。它們還為存儲和檢索數據提供了強大的支持。

當您需要管理多個前端時,REST API 是首選的應用程序。您可以從移動和 Web 應用程序請求您收到的數據。您可以構建一個可供您想要的所有客戶端應用程序使用的後端,這不是很棒嗎?我當然認為是!

在各種情況下使用服務靜態文件。提供 HTML 文件、圖像、CSS 樣式表和 JavaScript 腳本。所有都被視為靜態文件,它們都可以通過 Express 提供。這最常用於創建登錄頁面和其他前端應用程序,例如單頁應用程序。隨意將這種技術用於您的所有應用程序。了解如何提供圖像和 CSS 等靜態文件總是很有用的!

關於混合應用程序有什麼要說的?嗯,首先。請,如果您可以訪問兩個 Web 服務器,請將應用程序分開。在一個上創建 REST API,在另一個上創建 SPA。但是,如果您沒有那種奢侈,那麼保留它就可以了。否則,此應用組合在性能方面是最好的。

開始構建東西吧!

所有這些技術都是有效的並且完全可以使用。只需選擇一個並開始構建!自己動手會學到最多。

希望你們喜歡閱讀這篇文章,就像我喜歡寫它一樣。直到下一次,保持好奇,玩得開心。

您認為本教程會對某人有所幫助嗎?不要猶豫分享。如果你喜歡它,請在下面的評論中告訴我。


Tutorial JavaScript 教程
  1. setTimeout 只運行一次?

  2. JavaScript:如何將消息打印到錯誤控制台?

  3. 使用 React.useEffect() 獲取數據

  4. 您更喜歡 indexedDB 的哪種策略?

  5. 我想更改 html5-canvas 中圖像內圖像的顏色

  6. 使用 TypeScript 泛型來增強您的 React 組件並使其可重用

  7. 使用 YUI3 創建一個可擴展的小部件:第 4 部分

  1. 是否有任何用於 Web SQL (javascript) 的 ORM 框架?

  2. Angular 獨立組件及其對模塊化的影響

  3. 如何一次存儲在狀態中動態生成的 2 個輸入的值

  4. 📚 來自 dev.to 和網絡的很棒的鏈接 #6

  5. 反應:警報窗口

  6. Postman 中的自動授權🔒

  7. 提供 JavaScript 文件時,使用 application/javascript 還是 application/x-javascript 更好

  1. Elm in Practice - 事件、模式匹配、Maybe、Dict 和實現轉換器邏輯

  2. 所以你想做一個 Twitter 機器人 (2.5/3)

  3. i18next 和 ReactJS 與 SimpleLocalize.io 的國際化

  4. Rustacean 做 Javascript