###### tags: `筆記` # 【筆記】 第一個 Fullstack Project - Newsletter Signup Page ## 功能 一個簡單的訂閱畫面,輸入資料(姓名、Email Address),按下 Singup 按鈕,跳轉至「成功」訂閱畫面或是「失敗」訂閱畫面。 利用 Mailchimp 作為收集 Email Address 的後台資料庫。 最後使用 Railway 部署至網路上。 ## 連結 1. [GitHub repo](https://github.com/jovi920204/Newsletter-Signup-Page) 2. [網站連結](https://newsletter-signup-page-jovi-chang.up.railway.app) ## 展示畫面 ### 訂閱畫面(主畫面) ![](https://i.imgur.com/pNjiJ6U.png) 輸入測試資訊(Bob、Chang、BobChang@email.com) ![](https://i.imgur.com/MOHOjCP.png) ### 成功訂閱畫面 ![](https://i.imgur.com/WGhm40u.png) ### 失敗訂閱畫面 點擊「Try again!」按鈕,可以返回主畫面重新訂閱 ![](https://i.imgur.com/twWgvDo.png) ### Mailchimp 後台數據 ![](https://i.imgur.com/qY9846g.png) ## 程式碼解析 1. 初始化 ```javascript= // jshint esversion: 6 const express = require("express"); const bodyParser = require("body-parser"); const request = require("request"); const https = require("https") const app = express(); app.use(express.static("public")); app.use(bodyParser.urlencoded({extended: true})); ``` - 當 app 在使用 bodyParser 時,要記得啟用 urlencoded。 2. 導向主畫面 ```javascript= app.get("/", function(req, res){ res.sendFile(__dirname + "/signup.html"); }); ``` - `__dirname` 會回傳主機從根目錄到現在這個目錄的路徑,確保在不同 Server 上執行時,路徑都能夠正確。 3. 當表單送出,要做的事情 ```javascript= app.post("/", function(req, res){ // 從表單中擷取使用者輸入的資料 const firstName = req.body.firstName; const lastName = req.body.lastName; const email = req.body.email; // 包裝成 json 格式,這些名稱是根據 mailchimp 所提供的資料 const data = { members: [ { email_address: email, status: "subscribed", merge_fields: { FNAME: firstName, LNAME: lastName } } ] } // 原先的 json data 要經過 stringify 才能夠發送給 mailchimp const jsonData = JSON.stringify(data); // 以下為使用 https request 向 mailchimp 請求 const url = "https://<dc>.api.mailchimp.com/3.0/lists/<LIST_ID>" const options = { method: "POST", auth: "<NAME>:" + "<YOUR API KEY>" } // 先宣告 request 為 https.request 函式 const request = https.request(url, options, function(response){ response.on("data", function(data){ // 使用 response.statusCode 得知 requst 的狀態,例如 404 就代表 error、200 代表 OK const status = response.statusCode; if (status === 200){ res.sendFile(__dirname + "/success.html"); } else{ res.sendFile(__dirname + "/failure.html"); } }); }); // 執行 https.request,並且發送訂閱者的資料 request.write(jsonData); request.end(); }); ``` 4. 當 POST 到 "/failure" 這個路徑時,要做的事情 ```javascript= app.post("/failure", function(req, res){ res.redirect("/"); }); ``` 5. listent ```javascript= app.listen(process.env.PORT || 3000, function(){ console.log("Server is running on port 3000"); }); ``` ## 過程中額外學到的事情 1. 使用 Railway 取代 Heroku 現在 Heroku 已經不提供免費的流量及空間部署自己的 Server,在網友的推薦下,我使用 Railway 部署,發現只要把程式碼放到 GitHub 上,就真的是「一鍵部署」。 而且他提供的使用量足夠我這個 Web 開發新手架設自己的伺服器。 2. .env 因為要部署到 Railway 上,那們`app.listen()`就不能把`PORT`固定在 3000,而是交由 Server 空間提供者來自動決定,所以這邊就需要用到`process.env.PORT`,讓程式自動從環境參數中提取對應的資料。 我原先在設定 mailchimp 的 API Key 時,就直接打在程式碼當中,部署沒多久後,就收到 mailchimp 的來信,說我公開了 API Key,所以把那組 Key 值給 Disabled。此時我才發現我做了非常蠢的事情。後來才知道要把這個資訊寫在 .env 裡面,方法是到 Railway 的 Variables 設定頁面中,新增變數,並且在程式碼中修改呼叫 API Key 的方法,我改寫成 `process.env.API`,就大功告成了。 ![](https://i.imgur.com/F0e4OKi.png) 3. 移除 node_modules 在實作專案時,一定會`$ npm install <module>`,然後就會有 module 本體在專案資料夾底下,因為這是小小的專案,所以檔案根本不會很大,但是光看一個 module 裡面的東西,就有很多了,更何況是大專案,再者,因為有`package.json`,在使用 npm 服務時一定要先輸入 `$ npm init`,就會建立此專案的資訊,所以不管是誰拿到你的專案,只要根據這個`package.json`就可以建置相應的環境,執行你的專案。