這個是web2.0的東西,不像之前1.0版的前端後端並重,這個比較吃前端。
1.0版本是操作寫在render裡面,後端import render,對他進行操作。
而2.0是把東西都放在前端,不過前端使用fetch去和後端進行資料交互
ajax 和 fetch –> ajax & fetch & axios
注意!!,使用fetch要利用onclick觸發函式,所以form的最後不是用
type = "submit, 而是type="button"
var R = {}
// 這邊的東西都是前端的
// 相當於前端的router,利用hash(#後面的)去操作
window.onhashchange = async function () {
var r
// #後面的東西(包含) // window.location.ref: 全部的url
var tokens = window.location.hash.split('/') // 用/把標籤隔開放入陣列(str to list)
console.log('tokens=', tokens)
switch (tokens[0]) {
case '#show':
// 這裡使用fetch的get,先到/post/:id呼叫後端的show,show把文字檔丟到網站上後
// 再用r.json把字串轉json,最後放到show(post)裡面呈現
r = await window.fetch('/post/' + tokens[1])
let post = await r.json()
R.show(post)
break
case '#new':
R.new()
break
default:
r = await window.fetch('/list')
let posts = await r.json()
R.list(posts)
break
}
}
window.onload = function () {
// hash(#後面的)有任何改變就會觸發
window.onhashchange()
}
// 把內容丟到html裡面(title 放到網站標題,id = 'content'的區塊填資料進去)
R.layout = function (title, content) {
document.querySelector('title').innerText = title
document.querySelector('#content').innerHTML = content
}
R.list = function (posts) {
let list = []
for (let post of posts) {
list.push(`
<li>
<h2>${post.title}</h2>
<p><a id="show${post.id}" href="#show/${post.id}">Read post</a></p>
</li>
`)
}
let content = `
<h1>Posts</h1>
<p>You have <strong>${posts.length}</strong> posts!</p>
<p><a id="createPost" href="#new">Create a Post</a></p>
<ul id="posts">
${list.join('\n')}
</ul>
`
return R.layout('Posts', content)
}
R.new = function () {
return R.layout('New Post', `
<h1>New Post</h1>
<p>Create a new post.</p>
<form>
<p><input id="title" type="text" placeholder="Title" name="title"></p>
<p><textarea id="body" placeholder="Contents" name="body"></textarea></p>
<p><input id="savePost" type="button" onclick="R.savePost()" value="Create"></p>
</form>
`)
}
R.show = function (post) {
return R.layout(post.title, `
<h1>${post.title}</h1>
<p>${post.body}</p>
`)
}
// 之前的寫法是用server端把表單裡面的東西拿出來,這個是用客戶端,比較省錢 // 在R.new裡面呼叫
R.savePost = async function () {
let title = document.querySelector('#title').value
let body = document.querySelector('#body').value
// 把東西丟到 /post 這邊可以觸發後端的create函式
let r = await window.fetch('/post', {
// 把json物件轉成字串
body: JSON.stringify({title: title, body: body}),
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
})
window.location.hash = '#list'
return r
}
後端接收的程式碼需要加上ctx.response.body = “???”,讓網頁有內容,才不會報錯(網頁不會顯示)
fetch可以取得當前狀態,由server回傳,200是成功,其他的則會報錯
let r = await window.fetch('/login', {
// 把json物件轉成字串
body: JSON.stringify({username: username, password: password}),
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
})
console.log("r.status = " + r.status) // 200 成功
// 對應到後端的ctx.response.status
fetch可以取得get的內容,利用then把他的promise物件轉成文字:
let r = window.fetch('/login', {
// 把json物件轉成字串
body: JSON.stringify({username: username, password: password}),
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
})
r.test().then(function(data) {
console.log(data); // this will be a string --> 對應到後端的ctx.response.body
if(data=="success") {
window.location.hash = '#loginSuccess' // 切換到成功頁面
sideNav.login()
}
else window.location.hash = '#loginFail'
});
前端console.log在網頁看,後端console.log在terminal裡面看