PHP 與 API 拿取資料的差異
PHP
- 把資料利用 SQL 指令拿出來
- 把資料 HTML 跟結合(UI)再一起
- 回傳 HTML
browser render: 留言板
==這時候是 server-side render,在伺服器端就把資料跟 HTML 綁好回傳,所以瀏覽器接收到的資料已經有介面,就可以直接顯示。==
API
- 把資料拿出來
- 變成某種格式(JSON),因為沒有與 HTML 結合所以不會有介面,只是資料
- 回傳
透過 JS render => 顯示資料
==資料回傳時 HTML 還是空的,因此瀏覽器在拿到後端資料還需要經過 JS render 來動態顯示資料。==
參考資料:跟著小明一起搞懂技術名詞:MVC、SPA 與 SSR
用 PHP 實作 API:列出所有文章
// 以上都與 index.php 相同
// 將 SQL 抓的資料以陣列形式印出
while($row = $result->fetch_assoc()) {
array_push($comments, array(
"id" => $row["id"],
"username" => $row["username"],
"nickname" => $row["nickname"],
"content" => $row["content"],
"created_at" => $row["created_at"]
));
}
// 將陣列轉成 JSON 格式
$json = array(
"comments" => $comments
);
$response = json_encode($json);
// 編碼讓瀏覽器可以讀取
header('Content-type:application/json;charset=utf-8');
echo $response;
用 PHP 實作 API:新增文章
<?php
require_once('conn.php');
header('Content-type:application/json;charset=utf-8');
if (empty($_POST['content']))
{
$json = array(
"ok" => false,
"message" => "Please input content"
);
$response = json_encode($json);
echo $response;
die();
}
$username = $_POST['username'];
$content = $_POST['content'];
$sql = "INSERT INTO ericcch24_comments(username, content) VALUES(?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ss', $username, $content);
$result = $stmt->execute();
if (!$result) {
$json = array(
"ok" => false,
"message" => die($conn->error)
);
$response = json_encode($json);
echo $response;
die();
}
$json = array(
"ok" => true, //新增成功時為 ok 狀態
"message" => "Success"
);
$response = json_encode($json);
echo $response;
?>
透過前端串接 API
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>留言板</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header class="warning">
<strong>注意!本站為練習用網站,因教學用途刻意忽略資安的實作,註冊時請勿使用任何真實的帳號或密碼。</strong>
</header>
<main class="board">
<h1 class="board__title">Comments</h1>
<form class="board__new-comment-form">
<textarea name="content" rows="5"></textarea>
<input class="board__submit-btn" type="submit" />
</form>
<div class="board__hr"></div>
<section>
</section>
</main>
</body>
<script>
//用 ajax 取得資料後放到 html 上面
let request = new XMLHttpRequest();
request.open('GET', 'api_comments.php', true);
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
// Success!
let resp = this.response;
let json = JSON.parse(resp);
let comments = json.comments;
for (let i = 0; i < comments.length; i++) {
let comment = comments[i];
let div = document.createElement('div');
div.classList.add('card');
div.innerHTML = `
<div class="card__avatar"></div>
<div class="card__body">
<div class="card__info">
<span class="card__author">
${comment.nickname}(@${comment.username})
</span>
<span class="card__time">
${comment.created_at}
</span>
</div>
<p class="card__content">${encodeHTML(comment.content)}</p>
</div>
`
document.querySelector('section').appendChild(div);
}
}
};
request.send();
let form = document.querySelector('.board__new-comment-form');
form.addEventListener('submit', function(e) {
e.preventDefault();
let content = document.querySelector('textarea[name=content]').value;
let request = new XMLHttpRequest();
request.open('POST', 'api_add_comment.php', true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.send("username=ooo&content=" + encodeURIComponent(content));
request.onload = function() {
if (this.status >= 200 && this.status < 400) {
let resp = this.response;
let json = JSON.parse(resp)
if (json.ok) {
location.reload() // 有成功新增留言就重新整理
} else {
alert(json.message)
}
}
}
})
function encodeHTML(s) {
return s.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
}
</script>
</html>