# 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 } ```