# Node.js
1. 物件
var a = { firstName: 'James', lastName: 'Bond' }
2. npm
- 只會在單一資料夾裡安裝
npm install 套件
npm -i --save 套件
- 會在全域中安裝
npm install -g 套件
- 解除安裝
npm uninstall 套件
3. 內建的 http module
- ex.
var http=require('http');
var server=http.createServer(function(req,res){
if(req.url=='/'){
res.writeHead(200,{'Content-Type':'text/html'});
res.write('<html><body>This is Home Page.</body></html>');
res.end();
}else if(req.url=='/student'){
res.writeHead(200,{'Content-Type':'text/html'});
res.write('<html><body>This is student Page.</body></html>');
res.end();
}else if(req.url=='/admin'){
res.writeHead(200,{'Content-Type':'text/html'});
res.write('<html><body>This is admin Page.</body></html>');
res.end();
}else
res.end('Invalid Request!');
});
server.listen(5000);
4. express
- 安裝
npm install express --save # -- save 會有 .json 檔存放套件資訊
- 路由
app.get('/', function (req, res) {
res.send`("<html><body><h1>Hello World</h1></body></html>")`;
});
var server = app.listen(5000, function () {
console.log('Node server is running..');
});
5. express 呼叫寫好的 html
- 安裝 body-parser
npm install body-parser
-ex.
var express = require('express');
var app = express();
var bodyParser = require("body-parser");
app.use(bodyParser.urlencoded({ extended: false }));
app.get('/', function (req, res) {
res.sendFile(__dirname+'/templates/test.html'); // ___
});
var server = app.listen(5000, function () {
console.log('Node server is running..');
});
6. 永遠執行 .js
- 安裝
sudo npm install -g forever # 要為全域的
- 執行
forever start test.js
- 查看執行中的檔案
forever list
7. 連線到 mariadb
- 安裝
sudo npm install mariadb
- ex.
const db = require("mariadb");
const pool = db.createPool({
host : 'localhost',
user : 'wang',
password : 'wang313',
database : 'clinic'
});
async function connect() {
let conn;
try {
let conn = await pool.getConnection();
let rows = await conn.query('select * from test');
console.log(rows);
}
catch(err) {
console.log(err);
}
}
connect()
8. jade-template engine
- 安裝
sudo npm install jade
- 建立資料夾放 .jade 檔,預設路徑為相同路徑下的 views 資料夾
vi ./views/test.jade
- ex.
app.set("view engine", "jade");
app.set("views", "jade"); // 設定資料夾名稱,預設為 views
app.get('/', function (req, res) {
res.render('test'); // path = ./jade/test.jade
});
9. 傳送資料
- vi .js
app.get('/', async function (req, res) {
var db = require('mariadb');
const pool = db.createPool({
host : 'localhost',
user : 'wang',
password : 'wang313',
database : 'clinic'
});
let conn = await pool.getConnection();
let rows = await conn.query('select * from test');
res.render('test',{test:rows});
});
- vi .jade
doctype html
html
head
title 新增病患資料
body
ul
each item in test
li=item.a
10. 接收資料
- 前端
- 後端
要記得加 index
- ex.
let order = await conn.query('select pa_num from doctors where dId = ?;', req.body.dId);
console.log(order[0].pa_num);
- 前端
用 JSON.stringify 把 [Object object] 的 value 拿出來
11. sort
- ex. rec 是 json, 用 rec 裡的 r_num 大小來排序
rec.sort(function(a,b){
return a.r_num - b.r_num;
});
- ex.
axios.get('/data').then(function(response) {
JSON.stringify(response.data[i].pId)
})
11. 時區問題
- 帶參數執行
env TZ='Taiwan/Taipei' node test.js
12. redirect 帶參數
var string = encodeURIComponent('1');
res.redirect('/?valid=' + string);
13. api 回傳 json 給 html
- api
return res.json({a : 1})
- html
<script>
(async() => {
const {data : rec} = await axios.get('/records');
})();
</script>
14. jwt cookie
- 設定 cookie, 到 api, 先回傳 cookie,res.cookie 完可以再回傳別的(res.json、sendfile)
const {data : rec} = await axios.get('/records');
const token = jwt.sign({ data, exp: Math.floor(Date.now() / 1000) + (60 * 15) }, 'my_secret_ key')
res.cookie('token', token, { httpOnly: false, secure: false, maxAge: 3600000 });
- 路由查看 cookie,
const user = jwt.verify(req.cookies.token, 'my_secret_key');
- html 接收 cookie
-> 先到路由設定回傳 cookie 值
router.get('/dId', function(req, res) {
const user = jwt.verify(req.cookies.token, 'my_secret_key');
return res.json({dId : user.data.aId});
});
-> 再到 html 接收
const {data : user} = await axios.get('/docMain/dId');
15. 轉到其他網址
- 第一種
res.statusCode = 302;
res.setHeader("Location", "http://localhost:8080/login");
res.end(); // setHeader 的 end 要 ()
- 第二種
res.redirect('/login')
res.end // 不用 ()
16. 好用的 js 套件網站
bestofjs
17. cookie
- 設置 cookie
```
const data = {update_rId : req.body.rId};
const update_rId = jwt.sign({data, exp: Math.floor(Date.now() / 1000) + (60 * 15) }, 'my_secret_key'); // 加密
res.cookie('update_rId', update_rId, { httpOnly: false, secure: false, maxAge: 3600000 })
```
- 解 cookie
``const user = jwt.verify(req.cookies.token_name, 'my_secret_key');``
- error : mariadb too many connections
close the pool
``pool.end();``
- show Promise { <pending> }
要加上 then
let userToken = AuthUser(data) console.log(userToken) // Promise { <pending> }
userToken.then(function(result) { console.log(result) // "Some User token" })
- 直接呼叫函式
document.addEventListener("keyup", async(event) => {int a = 0;}
- get url, 加上參數
window.location.href = "/ckPatients?view=true"
# syntax sugar
- 教學
https://sophiali.dev/syntactic-sugar-examples-javascript
- <b>IF</b>
condition ? expressionIfTrue : expressionIfFalse
ex.
```
int i = 2;
i > 1 ? console.log('I am true') : console.log('I am false');
```
output = I am true
# socket.io-聊天室
- 教學 <br/> https://single9.net/2017/12/node-js-%e8%88%87-socket-io-%e5%8d%b3%e6%99%82%e8%81%8a%e5%a4%a9%e5%ae%a4%e5%af%a6%e4%bd%9c/
- copy function
```
function cpContent() { copy the content to clipboard
var all_need_copy = getClass('copy');
var total_str = '';
// add the value needed to be copied
for (let i = 0;i < all_need_copy.length;i++) {
total_str += all_need_copy[i].value;
total_str += "<new_element>";
}
// create a temporary textarea to place the value of copy
var el = document.createElement('textarea');
el.value += total_str; // add the value
// make textarea unseen and unused
el.setAttribute('readonly', '');
el.style = {position: 'absolute', left: '‑9999px'};
document.body.appendChild(el);
el.select();
var copy_suc = document.execCommand('copy');
alert(copy_suc ? 'copy successfully' : 'copy failed'); //alert successful or failed
document.body.removeChild(el); // remove copt textarea
}
```