Last active
May 1, 2017 05:22
-
-
Save pjchender/b578f0a127d8d09124d2436e9e9b720e to your computer and use it in GitHub Desktop.
[Treehouse][Node]Build a Simple Dynamic Site with Node.js @ Treehouse
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var router = require('./router.js') | |
// 問題:我們希望能夠用瀏覽器的方式查詢使用者在 treehouse 的點數 | |
// 解決:使用 NodeJS 來展現檔案 | |
// 1. 建立一個網路伺服器 | |
const http = require('http') | |
const hostname = '127.0.0.1' | |
const port = 3000 | |
const server = http.createServer((request, response) => { | |
router.home(request, response) | |
router.user(request, response) | |
}) | |
server.listen(port, hostname, () => { | |
console.log(`Server running at http://${hostname}:${port}/`) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<div id="profile"> | |
<img src="{{avatarUrl}}" alt="Avatar" id="avatar"> | |
<p><span>{{username}}</span></p> | |
<ul> | |
<li><span>{{badges}}</span> Badges earned</li> | |
<li><span>{{javaScriptPoints}}</span> JavaScript points</li> | |
<li><a href="/">search again</a></li> | |
</ul> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs') | |
// 將模版 {{}} 填入值 | |
// mergeValue (陣列, 內容) | |
function mergeValue (values, content) { | |
// 疊代取得 key 值 | |
for (let item in values) { | |
// 將所有 {{key}} 取代成 values 物件中對應的 value | |
content = content.replace(`{{${item}}}`, values[item]) | |
} | |
// 回傳將資料代入 template 後的 content | |
return content | |
} | |
// 選擇模版,要填入的值,並回傳結果 | |
// view(模版檔名,填入的值,寫入回應) | |
function view (templateName, values, response) { | |
// 讀取 Template 檔案 | |
var fileContents = fs.readFileSync('./views/' + templateName + '.html', {encoding: 'utf8'}) | |
// 將值塞入模版中 | |
fileContents = mergeValue(values, fileContents) | |
// 將成品回傳 | |
response.write(fileContents) | |
} | |
module.exports.view = view |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Profile = require('./profile.js') | |
var render = require('./render.js') | |
var queryString = require('querystring') | |
// 處理 HTTP Route GET / POST / (例如,Home) | |
function homeRoute (request, response) { | |
// if url == "/" && GET | |
if (request.method.toLowerCase() === 'get'){ | |
if (request.url === '/') { | |
// show search | |
response.statusCode = 200 | |
response.setHeader('Content-Type', 'text/html') | |
render.view('header', {}, response) | |
render.view('search', {}, response) | |
render.view('footer', {}, response) | |
} | |
} else { | |
// if url == "/" && POST | |
// 從 post body 取得資料 | |
request.on('data', function (postBody) { | |
// 取得 username | |
let query = queryString.parse(postBody.toString()) | |
// redirect to /:username | |
response.writeHead(303, {'Location': '/' + query.username}) | |
response.end() | |
}) | |
} | |
} | |
// 處理 HTTP Route GET /:username (例如,/chalkers) | |
// if url == "/..." | |
function userRoute (request, response) { | |
var username = request.url.replace('/', '') | |
if (username.length > 0) { | |
response.statusCode = 200 | |
response.setHeader('Content-Type', 'text/html') | |
render.view('header', {}, response) | |
// 從 Treehouse 取的 JSON 檔 | |
var studentProfile = new Profile(username) | |
// on "end" | |
studentProfile.on('end', function (profileJSON) { | |
// show profile | |
// 儲存所需要的資料 | |
var values = { | |
avatarUrl: profileJSON.gravator_url, | |
username: profileJSON.profile_name, | |
badges: profileJSON.badges.length, | |
javaScriptPoints: profileJSON.points.JavaScript | |
} | |
// 簡單的回覆 | |
render.view('profile', values, response) | |
render.view('footer', {}, response) | |
}) | |
// on "error" | |
studentProfile.on('error', function (error) { | |
render.view('error', {errorMessage: error.message}, response) | |
render.view('search', {}, response) | |
render.view('footer', {}, response) | |
}) | |
} | |
} | |
module.exports.home = homeRoute | |
module.exports.user = userRoute |
router.js
建立路由相關
- 使用
req.method
來取得 request 的方法(例如,GET) - 使用
req.url
來取得 request 的 URL - 使用
res.setHeader('Content-Type', 'text/html')
來設定 response 的 header - 使用
res.writeHead(303, {'Location': '/' + query.username})
來寫和 header 有關的訊息 - 使用
res.end()
表示結束 response
// 載入模組
var Profile = require('./profile.js')
var render = require('./render.js')
var queryString = require('querystring')
function homeRoute (request, response) {
// 如果網址是 "/" 且為 get
if (request.url === '/') {
// 顯示結果
response.statusCode = 200
response.setHeader('Content-Type', 'text/plain')
response.write('Header\n')
response.end('Footer\n')
}
}
對 request 做一些事
request.on('data', postBody => {
let query = queryString.parse(postBody.toString())
}
對 response 做一些事
response.statusCode = 200
response.setHeader('Content-Type', 'text/plain')
response.write('寫入 response 內容')
response.end('response 結尾') // 在這之後不能再寫入 response
render.js
[渲染(render)模版]
- 使用 `replace('target', 'value') ,將模版的內容填入資料
- 使用
fs.readFileSync('./views/' + templateName + '.html', {encoding: 'utf8'})
讀取檔案內容 - 使用
res.write(...)
寫入網頁內容
var fs = require('fs')
// 將模版 {{}} 填入值
function mergeValue (values, content) {
// 疊代取得 key 值
for (let item in values) {
// 將所有 {{key}} 取代成 values 物件中對應的 value
content = content.replace(`{{${item}}}`, values[item])
}
// 回傳將資料代入 template 後的 content
return content
}
// 選擇模版,要填入的值,並回傳結果
function view (templateName, values, response) {
// 讀取 Template 檔案
var fileContents = fs.readFileSync('./views/' + templateName + '.html', {encoding: 'utf8'})
// 將值塞入模版中
fileContents = mergeValue(values, fileContents)
// 將成品回傳
response.write(fileContents)
}
module.exports.view = view
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
app.js
[建立伺服器]