因為是跨網域存取 API,所以 API 都要記得加上 header('Access-Control-Allow-Origin: *');
先打造 UI ,有用到 bootstrap 和 jquery
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>留言板</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css"
integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">
<style>
.card {
margin-top: 12px;
}
</style>
</head>
<body>
<div class="container">
<form class="add-comment-form">
<div class="form-group">
<label for="form-nickname">暱稱</label>
<input name="nickname" type="text" class="form-control" id="exampleInputEmail1">
</div>
<div class="form-group">
<label for="content-textarea">留言內容</label>
<textarea name='content' class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
<button type="submit" class="btn btn-primary">送出</button>
</form>
<div class="comments">
</div>
</div>
</body>
</html>
出來圖案長這樣
js 部分
拿 API
$(document).ready(() => {
$.ajax({
url: 'http://localhost/hw1_12/api_comments.php?site_key=tzu',
}).done(function (data) {
if (!data.ok) {
alert(data.message)
return
}
});
})
用迴圈顯現出來,資料要用 escape() 防 XSS
const comments = data.discussions;
for (let comment of comments) {
$('.comments').append(`
<div class="card">
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">${escape(comment.nickname)}</h5>
<p>${comment.created_at}</p>
</div>
<p class="card-text">${escape(comment.content)}</p>
</div>
</div>
`)
}
function escape(toOutput) {
return toOutput.replace(/\&/g, '&')
.replace(/\</g, '<')
.replace(/\>/g, '>')
.replace(/\"/g, '"')
.replace(/\'/g, ''')
.replace(/\//g, '/');
}
post 資料到後端
監聽表單,先阻止預設行為 e.preventDefault();
,用 POST 傳 site_key、nickname、content 到 API
$('.add-comment-form').submit(e => {
e.preventDefault();
$.ajax({
type: 'POST',
url: 'http://localhost/hw1_12/api_add_comments.php',
data: {
site_key: 'tzu',
nickname: $('input[name=nickname]').val(),
content: $('textarea[name=content]').val()
}
}).done(function (data) {
if (!data.ok) {
alert(data.message)
return
}
});
})
傳到後端成功之後,有幾種作法,直接把剛剛新增成功的留言內容放上去,另外一種就是再 query 一次 API,把 API 裡面新的內容放上去,先把原本新增的內容用一個 function 包起來
function appendCommentToDOM(container, comment) {
const html = `
<div class="card">
<div class="card-body">
<div class="d-flex justify-content-between">
<h5 class="card-title">${escape(comment.nickname)}</h5>
<p>${comment.created_at}</p>
</div>
<p class="card-text">${escape(comment.content)}</p>
</div>
</div>
`
container.append(html)
}
這樣顯示時,只要把參數傳進去就好
const commentDOM = $('.comments')
const comments = data.discussions;
for (let comment of comments) {
appendCommentToDOM(commentDOM, comment)
}
回到之前資料傳到後端成功之後,在要做的事情就可以一樣放 appendCommentToDOM 這個 function 就好
const commentsDOM = $('.comments')
const newCommentData = {
site_key: 'tzu',
nickname: $('input[name=nickname]').val(),
content: $('textarea[name=content]').val()
}
appendCommentToDOM(commentsDOM, newCommentData)
成功之後傳個空字串清空值
$('input[name=nickname]').val('')
$('textarea[name=content]').val('')