W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
你想在網(wǎng)絡(luò)上創(chuàng)建一個HTTP服務(wù)器。在這個方法中,我們將逐步從最小的服務(wù)器成為一個功能鍵值存儲。
我們將使用node.js HTTP庫并在Coffeescript中創(chuàng)建最簡單的web服務(wù)器。
我們可以通過導(dǎo)入node.js HTTP模塊開始。這會包含createServer,一個簡單的請求處理程序返回HTTP服務(wù)器。我們可以使用該服務(wù)器監(jiān)聽TCP端口。
http = require 'http'
server = http.createServer (req, res) -> res.end 'hi\n'
server.listen 8000
要運行這個例子,只需放在一個文件中并運行它。你可以用ctrl-c終止它。我們可以使用curl命令測試它,可用在大多數(shù)*nix平臺:
$ curl -D - http://localhost:8000/
HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked
hi
讓我們一點點來反饋服務(wù)器上發(fā)生的事情。這時,我們可以友好的對待用戶并提供他們一些HTTP頭文件。
http = require 'http'
server = http.createServer (req, res) ->
console.log req.method, req.url
data = 'hi\n'
res.writeHead 200,
'Content-Type': 'text/plain'
'Content-Length': data.length
res.end data
server.listen 8000
再次嘗試訪問它,但是這一次使用不同的URL路徑,比如http://localhost:8000/coffee
。你會看到這樣的服務(wù)器控制臺:
$ coffee http-server.coffee
GET /
GET /coffee
GET /user/1337
假如我們的網(wǎng)絡(luò)服務(wù)器能夠保存一些數(shù)據(jù)會怎么樣?我們將在通過GET方法請求檢索的元素中設(shè)法想出一個簡單的鍵值存儲。并提供一個關(guān)鍵路徑,服務(wù)器將請求返回相應(yīng)的值,如果不存在則返回404錯誤。
http = require 'http'
store = # we'll use a simple object as our store
foo: 'bar'
coffee: 'script'
server = http.createServer (req, res) ->
console.log req.method, req.url
value = store[req.url[1..]]
if not value
res.writeHead 404
else
res.writeHead 200,
'Content-Type': 'text/plain'
'Content-Length': value.length + 1
res.write value + '\n'
res.end()
server.listen 8000
我們可以試試幾種url,看看它們?nèi)绾位貞?yīng):
$ curl -D - http://localhost:8000/coffee
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 7
Connection: keep-alive
script
$ curl -D - http://localhost:8000/oops
HTTP/1.1 404 Not Found
Connection: keep-alive
Transfer-Encoding: chunked
text/plain是站不住腳的。如果我們使用application/json或text/xml會怎么樣?同時,我們的存儲檢索過程也可以用一點重構(gòu)——一些異常的拋出&處理怎么樣? 來看看我們能想出什么:
http = require 'http'
# known mime types
[any, json, xml] = ['*/*', 'application/json', 'text/xml']
# gets a value from the db in format [value, contentType]
get = (store, key, format) ->
value = store[key]
throw 'Unknown key' if not value
switch format
when any, json then [JSON.stringify({ key: key, value: value }), json]
when xml then ["<key>#{ key }</key>\n<value>#{ value }</value>", xml]
else throw 'Unknown format'
store =
foo: 'bar'
coffee: 'script'
server = http.createServer (req, res) ->
console.log req.method, req.url
try
key = req.url[1..]
[value, contentType] = get store, key, req.headers.accept
code = 200
catch error
contentType = 'text/plain'
value = error
code = 404
res.writeHead code,
'Content-Type': contentType
'Content-Length': value.length + 1
res.write value + '\n'
res.end()
server.listen 8000
這個服務(wù)器仍然會返回一個匹配給定鍵的值,如果不存在則返回404錯誤。但它根據(jù)標頭Accept將響應(yīng)在JSON或XML結(jié)構(gòu)中??捎H眼看一下:
$ curl http://localhost:8000/
Unknown key
$ curl http://localhost:8000/coffee
{"key":"coffee","value":"script"}
$ curl -H "Accept: text/xml" http://localhost:8000/coffee
<key>coffee</key>
<value>script</value>
$ curl -H "Accept: image/png" http://localhost:8000/coffee
Unknown format
我們的最后一步是提供客戶端存儲數(shù)據(jù)的能力。我們將通過監(jiān)聽POST請求來保持RESTiness。
http = require 'http'
# known mime types
[any, json, xml] = ['*/*', 'application/json', 'text/xml']
# gets a value from the db in format [value, contentType]
get = (store, key, format) ->
value = store[key]
throw 'Unknown key' if not value
switch format
when any, json then [JSON.stringify({ key: key, value: value }), json]
when xml then ["<key>#{ key }</key>\n<value>#{ value }</value>", xml]
else throw 'Unknown format'
# puts a value in the db
put = (store, key, value) ->
throw 'Invalid key' if not key or key is ''
store[key] = value
store =
foo: 'bar'
coffee: 'script'
# helper function that responds to the client
respond = (res, code, contentType, data) ->
res.writeHead code,
'Content-Type': contentType
'Content-Length': data.length
res.write data
res.end()
server = http.createServer (req, res) ->
console.log req.method, req.url
key = req.url[1..]
contentType = 'text/plain'
code = 404
switch req.method
when 'GET'
try
[value, contentType] = get store, key, req.headers.accept
code = 200
catch error
value = error
respond res, code, contentType, value + '\n'
when 'POST'
value = ''
req.on 'data', (chunk) -> value += chunk
req.on 'end', () ->
try
put store, key, value
value = ''
code = 200
catch error
value = error + '\n'
respond res, code, contentType, value
server.listen 8000
在一個POST請求中注意數(shù)據(jù)是如何接收的。通過在“數(shù)據(jù)”和“結(jié)束”請求對象的事件中附上一些處理程序,我們最終能夠從客戶端緩沖和保存數(shù)據(jù)。
$ curl -D - http://localhost:8000/cookie
HTTP/1.1 404 Not Found # ...
Unknown key
$ curl -D - -d "monster" http://localhost:8000/cookie
HTTP/1.1 200 OK # ...
$ curl -D - http://localhost:8000/cookie
HTTP/1.1 200 OK # ...
{"key":"cookie","value":"monster"}
給http.createServer一個函數(shù) (request,response) - >…… 它將返回一個服務(wù)器對象,我們可以用它來監(jiān)聽一個端口。讓服務(wù)器與request和response對象交互。使用server.listen 8000監(jiān)聽端口8000。
在這個問題上的API和整體信息,參考node.js http和https文檔頁面。此外,HTTP spec可能派上用場。
在服務(wù)器和開發(fā)人員之間創(chuàng)建一個層,允許開發(fā)人員做類似的事情:
server = layer.createServer
'GET /': (req, res) ->
...
'GET /page': (req, res) ->
...
'PUT /image': (req, res) ->
...
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: