2018年12月31日 星期一

【Express】如何把前端資料送到後端?body-parser+JQuery AJAX(或是表單)


▌非AJAX作法(表單做法)

  • 用form表單把資料post到特定路徑下面
  • 此做法會導致畫面重新reload
  • 表單資料會出現在req.body (name會是資料名稱)
  • Name是會POST到後端的重要參數(id只會在前端)
//html
<form action="/" method="POST">
     <input type="text" placeholder="IG帳號" name="account" id="submit_input" value="">
      <button id="button-describe" type="submit">訂閱</button>
</form>
//express
app.post('/', function (req, res) {
    console.log(req.body.account);
})

▌AJAX作法(JQuery作法)

//html
<input type="text" placeholder="IG帳號" id="subscriptionAccount" value="">
<button id="subscriptionButton" type="submit">訂閱</button>
  • 取得input資料,然後把他ajax到伺服器
  • data:{“content”:subscriptionAccount} 會把一個物件傳到後面
  • success:function(res) 可以得到後端伺服器的res(後端自己寫的)
//JQuery
$('#subscriptionButton').on('click', function () {
        var subscriptionAccount = $('#subscriptionAccount').val();
        if (subscriptionAccount == '') {
            toastr.info("請輸入帳號")
        }
        else{
            $.ajax({
                url: "/newaccount",
                dataType: "json",
                data:{"content":subscriptionAccount},
                method:"post",
                success:function(res){
                    console.log(res)
                    if(res.success){
                        toastr.info("訂閱成功");
                    }else{
                        toastr.info("帳號已存在");
                    }
                }
            });
        }
});
//Express.JS

app.post('/newaccount', function (req, res) {
    var content = req.body.content;
    var connectTofirebase = fireData.ref("AccountData").push();
    if(allAccount.indexOf(content) == -1){
        connectTofirebase.set({
            "account": content,
            "date": Date.now()
        }).then(function(){
            fireData.ref('AccountData').once('value',function(snapshot){
                res.send({
                    "success":true,
                    "result":snapshot.val(),
                    "message":"訂閱成功"
                });
            });
        });
    }

    else {
            res.send({
                "success":false,
                "message":"已存在該帳號"
            });
    }

})

▌後端的Express的API寫法

  • API寫法
 res.send({
                    "success":true,
                    "result":snapshot.val(),
                    "message":"訂閱成功"
                });

▌不管怎樣都要安裝body-parser

  • body-parser可以解析前端POST過來的「資料」
npm install body-parser  //安裝body-parser

▌設置參數

//express.js
var bodyParser = require('body-parser');
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
    extended: false
}));




【Heroku】Heroku部署



Heroku部署真的超簡單的,步驟真的很不複雜

訂閱尼桑上線囉!


 ▌Heroku部署
heroku login
git add .
git commit -am "make it better"
git push heroku master
git push heroku master  //把檔案推上去
heroku open  //打開網站

▌Package.json

  • 要記得告訴Heroku的engines
  • 要記得告訴Heroku有什麼npm的dependencies
  • 要記得告訴Heroku如何start
  "engines":{
    "node":"6.11.1"
  },
  "dependencies": {
    "jquery": "^3.3.1",
    "toastr": "^2.1.4"
  },
  "scripts": {
    "start": "node express.js"
  },


2018年12月23日 星期日

【Express】用ejs設定layout,不用重複引入一堆link&script


▌建立一個layout.ejs

在裡面放 <%-body%>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>訂閱尼桑</title>
    <link rel="stylesheet" href="/css/reset.css">
    <script src="/build/jquery.min.js"></script>
    <script src="/build/toastr.min.js"></script>
    <link rel="stylesheet" href="/css/toastr.min.css">
    <link rel="stylesheet" href="/css/style.css">

</head>

<body>
    <%-body%>
</body>
<script src="https://www.gstatic.com/firebasejs/5.7.1/firebase.js"></script>
<script src="/build/script.js"></script>

</html>

▌引入layout.ejs

<% layout('layout') %>
<div>我要的html內容</div>

【Express】用ejs模板渲染html /獲取後端傳來的參數


▌如何渲染html?

一直用res.send(“….“) 很浪費時間,因此可以用EJS/Pug之類的模板語言

▌在express設定使用ejs

npm install ejs-locals --save     //安裝ejs
  • 建立一個view的資料夾,放入ejs檔案(但他是html)
var express = require('express');
var app = express();
app.use(express.static('public'))
----下面這些設定可以直接貼上----
var engine = require('ejs-locals');
app.engine('ejs', engine);  //載入engine
app.set('views', './views') //設定到views資料夾 
app.set('view engine', 'ejs')    //設定ejs引擎
app.get('/', function (req, res) {
    res.render('index')
});
----上面這些設定可以直接貼上----

▌使用ejs獲取後端傳來的變數

  • 變數會放在res.render(‘index’, {變數}) 裡面
  • 在ejs中使用<%= 變數 %>就可以「獲取後端傳來的變數」
    <% - 變數 %> 會被渲染成html
app.get('/', function (req, res) {
    res.render('index', {
        'title': ['學習心得', '閱讀筆記', '最新文章']
    })
});
//傳入ejs(其實應該要用for寫,但我懶得整理)
            <div class="box3"><img src="/images/learining.gif" alt="">
                <h2>
                    <%= title[0]%>
                </h2>
            </div>
            <div class="box3"><img src="/images/book.gif" alt="">
                <h2>
                    <%=title[1]%>
                </h2>
            </div>
            <div class="box3"><img src="/images/article.png" alt="">
                <h2>
                    <%=title[2]%>
                </h2>
            </div>
        </div>

【Express】設定靜態檔案public目錄(使用ing/build需要)


▌為什麼要設定靜態檔案目錄?

因為img src不知道要去哪裡找照片,必須先設定一個目錄,它才知道要去哪裡找。
  • 設定靜態檔案:use(express.static('放靜態檔案的目錄名稱'))
var express = require('express');
var app = express();
app.use(express.static('public'))  //設定靜態檔案目錄
app.get('/', function (req, res) {
    res.send('<html><head></head><body><img src="/1.gif"></img></body></html>')

});
var port = process.env.PORT || 3000
app.listen(1222);

【Express】利用use()中介守門員來驗證嘗試登陸的使用者 / 處理錯誤路徑 / 處理錯誤程式碼


▌use()在幹嘛?

  • 用來當守門員,比如說要進入\user之前,要先經過use的函式驗證

▌use()可以放在get()前面當驗證

  • 當app被use時,通過next()才會進到下一個階段
var express = require('express');
var app = express();

app.use(function (req, res, next) {
    console.log("有人嘗試登陸了");
    next();    //先執行
})

app.get('/user', function (req, res) {
    res.send("WELCOME")
});

▌不用use寫守門員

  • app.get(‘路由’,守門員,function(req,res){…})
var check = function (req, res, next) {
    console.log("有人嘗試登陸了");
    next();
}
app.get('/user/:name', check, function (req, res) {
    res.send("WELCOME")
});

▌如何設定「404錯誤」?

在最後一行貼上res.status(404).send(“找不到路徑!”),當找不到路徑時就會進入到404
app.use(function (req, res, next) {      //1.先執行這一行
    console.log("有人嘗試登陸了");
    next();       //2.通過next()才會進去下面
})

app.get('/user', function (req, res) {    //3.進入user路由
    res.send("WELCOME")
});

app.use(function (req, res, next) {
    res.status(404).send("找不到路徑!")
})

▌如何設定「程式error」?

在最後一行貼上app.use(function (err, req, res, next) { res.status(500).send(“程式錯誤”)})
app.use(function (req, res, next) {
    console.log("有人嘗試登陸了");
    next();
})

app.get('/user/:name', function (req, res) {
    wow() //錯誤的程式碼
    res.send("WELCOME")

});

app.use(function (req, res, next) {
    res.status(404).send("找不到路徑:(")
})

app.use(function (err, req, res, next) {
    res.status(500).send("程式錯誤")
})

【Express】用params的去讀取路徑&用query去搜索資訊


params在做什麼?

params會傳到後端,用在讀取網址路徑所用

▌簡介

如果設定是app.get(‘/user/:name‘, function (req, res) {…}
當使用者輸入「http://localhost/user/nissen」,那nissen這個資料就會傳回伺服器,儲存在req.params這個物件中
console.log(req.params.name;) // nissen

▌範例

  • req.params會儲存:name中的資料
var express = require('express');
var app = express();

app.get('/user/:name', function (req, res) {
    var myName = req.params.name;  
    console.log(myName)
    res.send("Hello!" + myName);
});

var port = process.env.PORT || 3000; //如果前面是flase就會進入3000
app.listen(1222);

qurery在做什麼?

很常用在當在搜索一個大資料內容的細部資料(例如撈10筆資料、五個關鍵字、價格在100元以上的產品)
當使用者輸入「http://localhost/user/nissen?limit=20 & keyword=shirt & color=blue」,參數(query)就會被送到後端,讓後端使用這些參數

▌簡介

  • query可以用來做搜尋
    比如說使用者搜尋 ? limit=20 & keyword=shirt & color=red
    後端就會得到{ limit: ‘20’, keyword: ‘shirt’, color: ‘red’ }
  • 使用者輸入的資料,會存在伺服器的req.query當中
  • 可以用變數去儲存那些變數(像是:var limit = req.query.limit;)
var express = require('express');
var app = express();

app.get('/user/:name', function (req, res) {
    var myName = req.params.name;
    var limit = req.query.limit;
    var keyword = req.query.keyword;
    console.log(req.query)
    res.send("Hello!<br>" + myName + "搜尋" + limit + "筆資料");
});

var port = process.env.PORT || 3000; //如果前面是flase就會進入3000
app.listen(1222);

▌params和query有什麼差別?

  • params:用在讀取網址路徑所用。
  • query:常用在當在搜索一個大資料內容的細部資料(例如撈10筆資料、五個關鍵字、價格在100元以上的產品)

【JavaScript】用物件Mapping的方法

If的寫法 我們希望當變數是a時就回傳1,變數是b就回傳2,變數是c就會回傳3,一般寫法就是用if,但是這樣會很冗 ​ // IF style var word if(word == 'a'){ word = 1 } else if...