Chrome Pointer

2023年12月6日 星期三

Ajax-運用express和fetch的結合,在node.js上實作前端和後端api路由(Get和Post)的教學

 參考文章

💓Ajax-在node.js使用fetch時,常會碰到之問題"req.body返回值為空"詳解

💓使用MongoDB結合Express和Fetch來實作RESTful API簡單網站(包括用戶Post, Get, Update, Delete等功能)


project/ │ ├── app.js │ ├── public/ │ ├── index.html │ ├── demo_test.json │ ├── js/ │ │ └── script.js


app.js

const express = require("express")
const path = require("path")

const app = express()
const port =  3000
var bodyParser = require('body-parser') //這個必須存在

// Setting path for public directory
const static_path = path.join(__dirname, "public")
//變成絕對路徑 D:\qqq\public,nodejs使用絕對路徑較安全可靠,
在 Node 中使用相對路徑進行檔案讀取是很危險的, 建議一律都透過絕對路徑的方式來處理
app.use(express.static(static_path))  //如果要提供影像、CSS 檔案和 JavaScript 檔案等之類的靜態檔案,
public 的目錄中,提供影像、CSS 檔案和 JavaScript 檔案:
app.use(bodyParser.urlencoded(extended=true))
//extended預設為true 當你需要post的時候 會需要用到urlencoded
app.use(bodyParser.json()); //這個必須存在

// Handling request
app.post("/request2", (req, res) => {
    // 输出 JSON 格式
    var response = {
        name_recieved: req.body.first_name,
        designation_recieved: req.body.last_name
    }
    console.log(response)
    res.json(response)
})

app.post("/yo_fetch", (req, res) => {
    // 输出 JSON 格式
    //res.setHeader('Content-Type', 'application/json; charset=utf-8')
    var fetch_response = {
        fetch_name_recieved: req.body.fetch_title,
        fetch_body_recieved: req.body.fetch_body,
        important: req.body.important
    }
    console.log(fetch_response)
    res.send(fetch_response)
    //res.json(fetch_response) //send或josn都可以
})

// Server Setup
app.listen(port, () => {
    console.log(`server is running at ${port}`)
});


$.ajax 是使用Jquery來執行Ajax的api運用,

它是使用Ajax中的xhr來發出Get的。



https://randomuser.me/api/ 這網站每次點進去會隨機產生不同的api


public/js/script.js


let headers = {
    Authentication: 'secret',
    qqq: 'qqq',
    sexy: 'sexy boy'
}

const update = {
    fetch_title: "wei love",
    fetch_body: 'love love love',
    fetch_userId: 909,
    important: "You need body-parser,require body-parser"
};

const options = {
    method: 'POST',
    headers: {
        "Content-Type": "application/json",
    },
    body: JSON.stringify(update)
};


$(document).ready(function () {
    $("#submit").click(function () {
        $.ajax({
            url:"demo_test.json",
            dataType: "json",
            success:function(result){
                $("#div1").html(result.name+" @ "+result.age);
            },
            error: function () {
                $("#div1").html("thrownError");
            }
        })//下面是fetch的抓法
        fetch('demo_test.json',{headers:headers})
            .then((response) => {
                return response.json();  //把資料轉成JSON格式
            })
            .then( (response) => {
                console.log(response);
            })
            .catch((error) => {
                console.log(`Error花: ${error}`);
            })
        //下面開始是GET
        //https://randomuser.me/api/,第一個是URL,第二個是一堆参數,例如method、header等
        fetch('https://randomuser.me/api/',{headers:headers})
            .then((response) => {
                return response.json();  //把資料轉成JSON格式
            })
            .then( (response) => {
                console.log(response.info.seed);
                console.log(response);
                $("#front").html("seed: "+response.info.seed+" @ version: "+response.info.version);
            })
            .catch((error) => {
                console.log(`Error花: ${error}`);
            })
    });//下面開始是POST
    $("#fetch_go").click(function () {
        fetch('/yo_fetch', options)
            .then((response) => {
              return response.json();
            })
            .then((response) => {
              console.log(response);
              var fet_txt= document.querySelector("#fetch")
              var h2 = document.createElement("h2")
              var resp_txt= document.createTextNode(response.important+" @ "+response.fetch_name_recieved)
              h2.appendChild(resp_txt)
              fet_txt.appendChild(h2)
              //$("#fetch").html("<h2>"+response.important+"</h2>"+response.fetch_name_recieved);
            })//當我們post出去,並且讓server (nodejs的express)收到後,我們需要呼叫server端的變數,才能顯示出來
            //可以看f12>>network,裡面json檔的變數叫什麼,我們就要呼叫什麼。
            .catch(err => {
              console.log('Error花', err);
              $("#fetch").html("Error花");
            })
    });
    $("#idd_btn").click(function () {
        var idd = document.querySelector("#idd")
        console.log("response");
        fetch('https://reqres.in/api/users/'+idd.value,{headers:headers})
            .then((response) => {
                return response.json();  //把資料轉成JSON格式
            })
            .then( (response) => {
                console.log(response);
                var fet_idd= document.querySelector(".inpu_idd")
                fet_idd.textContent=response.data.email
            })
            .catch((error) => {
                console.log(`Error花: ${error}`);
            })
    });
});


public/index.html

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content=
        "width=device-width, initial-scale=1.0">
    <style>
        .container {
            width: 500px;
            margin: auto;
            text-align: center;
        }
    </style>
</head>

<body>
    <div class="container">
        <h1>
            Sending data to a node server using
            Ajax Request without Reloading Page
        </h1>
        <img src="cute.png">
        <button id="submit">submit</button>
        <form action="/request2" method="POST">
            First Name: <input type="text" name="first_name">  <br>
            Last Name: <input type="text" name="last_name"><br>
            <button id="submit2">submit2</button>
        </form>
       
        <span class="inpu_idd">打ID唷:</span><br/>
        <input type="text" id="idd"><br>
        <button id="idd_btn">idd</button>
   
    <div id="fetch"><h2>使用 fetch !!!!</h2></div>
    <button id="fetch_go">fetch_go</button>

    </div>
    <div id="div1"><h2>使用 jQuery AJAX 修改文本内容</h2></div>
    <div id="front"><h2>Front side</h2></div>
   

    <h1 class="demo">
        測試唷~~~
    </h1>
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"
        integrity=
        "sha256-/xUj+3OJU5yExlq6GSYGSHk7tPXikynS7ogEvDej/m4="
        crossorigin="anonymous">
    </script>
    <script src="js/script.js"></script>
</body>

</html>


public/demo_test.json

{
  "name": "John Doe",
  "age": 30,
  "isStudent": false,
  "courses": null
}

💛💛💛

---補充fetch功用---

fetch是javascript實行Restful api的功能,是Ajax的應用。

透過 "fetch" API,可以發送 GET、POST、PUT、DELETE 等不同類型的 HTTP 請求。

>>不需要server路由的Get和Post講解

下面程式碼為get範例

fetch('https://randomuser.me/api/',{headers:headers})
            .then((response) => {
                return response.json();  //把資料轉成JSON格式
            })

1. 當你需要得到的資料是從別的網站拿到的,

你可以直接Get下來並顯示在頁面上,

但若你有需要存進資料庫的需求,則還是需要建置server(Node.js ..)。


2. 你要把資料Post到別的網站上面,也可以直接用fetch實作,

但若你要Post的資料是在資料庫當中的話,還是需要建置server。


>>需要server路由的Get和Post講解

1. 當你需要讀取檔案內容(.json),並要將它顯示在網頁上時,

如果沒有server的話會讀不到,並發生錯誤。

 fetch('demo_test.json',{headers:headers})
            .then((response) => {
                return response.json();  //把資料轉成JSON格式
            })

2. 當你需要使用者輸入表單資料等,並要將資料Post傳入時,需要server設定路由。

3. 需要使用資料庫時,也會需要路由。


本文是使用Express在node.js上面設定路由。

const express = require('express');
const app = express();
app.post("/yo_fetch", (req, res) => {
    // 输出 JSON 格式
    //res.setHeader('Content-Type', 'application/json; charset=utf-8')
    var fetch_response = {
        fetch_name_recieved: req.body.fetch_title,
        fetch_body_recieved: req.body.fetch_body,
        important: req.body.important
    }
    console.log(fetch_response)
    res.send(fetch_response)
    //res.json(fetch_response) //send或josn都可以
})


建議大家實作的時候可以試試看,
如果只有使用前端的Fetch來post和get,
那麼network回傳的response會長怎樣?

如果有加上server端的express在nodejs設定路由Post和Get,
要怎麼設定api的寫法才可以從Fetch那邊接收到Post或Get的內容 等等。

這部份很重要,因為api的傳遞是前後端需要同心協力的地方,

藉由去看console和response可以更明白哪裡出錯,
還有api應該如何設定等內容。



一般https://reqres.in/api/users/'+idd.value,這個網站加上ID可以連進各個api當中,
有1~12個ID可以使用。


一般公司都會要求前後端能夠執行RESTful API,詳情可以參考這篇文章

沒有留言:

張貼留言

喜歡我的文章嗎? 喜歡的話可以留言回應我喔! ^^