2019年2月15日 星期五

[HTML] ribody

怕自己忘記,稍微紀錄一下。
各種各種理由(其中一個就是Vue,不能綁定在body上),導致時常需要一個包在body中的div,當作body來用,像這樣:
===
<body>
    <div id="divBody">
        <ALL CONTENT HERE>
    </div>
</body>
===.
以前我叫這玩意兒divBody,之後打算改一個更像關鍵字的名字,於是想叫他rib──肋骨,又索性改叫做ribody,一方面表示他就是用來取代body的,一方面這個單字是自創的,辨識性更高一點。

2019年2月14日 星期四

[Node.js] 用Express建立伺服器

首先npm install express。
通常會把伺服器寫在server.js裡。
首先使用express()建立一個網埠監聽器(貌似大家都稱他為app,不過在Electron中可能跟electron.app搞混,或是當我們需要多個網埠監聽器的時候,總之app這個名字是可以變的,反正就是變數名稱)。
===
const express = require("express");
const bodyParser = require("body-parser");

let app = express();
app.use(bodyParser.text());
app.use(bodyParser.urlencoded({ extended: true }));
===.
bodyParser是為了後面可以使用req.body來接收客戶端的資料。沒有使用bodyParser的話會導致req.body未定義。
基本的都OK了。接下來要先定義各種路由的監聽函式。簡單來說就是當客戶端GET「/about/」的時候,要用哪個listener回應;當客戶端POST「/weather/today/」的時候,又要用哪個listener回應。其中,「/about/」和「/weather/today/」就稱為路由。
在listener中,req表示客戶端傳來的請求,res代表準備送出的伺服器回應。
res.send(response)後,這個res就不能再被傳送第二次了。
===
app.get(route, function (req, res) {
  res.send("server response"); 
  res.send("this is no use"); // 這個send是無效的
}); 
===.
在客戶端,為了向伺服器傳送請求,通常是這樣做的:
===
// 客戶端
let xhttp = new XMLHttpRequest(); 
xhttp.onreadystatechange = function () {
  console.log(this.readyState); 
  console.log(this.status); 
  console.log(this.responseText); 
}; 
xhttp.open(method, url, async); 
xhttp.send("client request"); 
===.
所謂的method指的就是"GET"或"POST"(字串型別);async則是是否使用非同步處理。
在onreadystatechange的監聽器中,有關readyState和status的差異,可以參考W3School
簡單來說,readyState是指說一個請求是否被傳送出去了、是否收到回應了,其中4代表收到回應。status描述的則是伺服器對於你的請求給出了什麼樣的回應。200表示正常,404表示找不到你所請求的頁面等等。
一般來說若可以檢查到readyState === 4 && status === 200表示收到了正常的伺服器回應。
經過xhttp.send()之後,請求就會被傳送到伺服器。
由於前面有使用bodyParser,因此傳送到伺服器的附加資訊──也就是"client request"──可以由req.body取得。
===
app.get(route, function (req, res) {
  console.log(req.body); 
}); 
===.
基本上我的作法是這樣的:不論是req.body還是xhttp.send()的附加資訊,他們傳送和接收的都是字串。因此我會把JSON物件資訊先轉換為字串,接收後再解析回JSON物件。
===
// 客戶端
xhttp.send(JSON.stringify(content)); 
// 伺服端
console.log(JSON.parse(req.body)); 
===.
回到路由的部分,那個route可以是字串,比如"/about/",也可以是正規表達式。
註冊多個路由監聽函式的時候,先註冊的有高的優先權。
===
app.get("/", listener1); 
app.get("/", listener2); // 這個是無用的,因為會被上面那個監聽函式搶走。
===.
而我則是習慣讓所有請求都衝著"/"來,不管甚麼方法都用同一個函式監聽。
===
app.all("/", listener); 
===.
講了這麼多,沒有實際開始監聽是沒有用的。
這個頁面紀錄了較知名的服務所使用的網埠,盡量不要衝突。
===
app.listen(port);
===.

[HTML] ribody

怕自己忘記,稍微紀錄一下。 各種各種理由(其中一個就是Vue,不能綁定在body上),導致時常需要一個包在body中的div,當作body來用,像這樣: === <body>     <div id="divBody">   ...