W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
你想在網(wǎng)絡(luò)上創(chuàng)建一個(gè)HTTP服務(wù)器。在這個(gè)方法中,我們將逐步從最小的服務(wù)器成為一個(gè)功能鍵值存儲(chǔ)。
我們將使用node.js HTTP庫(kù)并在Coffeescript中創(chuàng)建最簡(jiǎn)單的web服務(wù)器。
我們可以通過(guò)導(dǎo)入node.js HTTP模塊開始。這會(huì)包含createServer,一個(gè)簡(jiǎn)單的請(qǐng)求處理程序返回HTTP服務(wù)器。我們可以使用該服務(wù)器監(jiān)聽TCP端口。
http = require 'http'
server = http.createServer (req, res) -> res.end 'hi\n'
server.listen 8000
要運(yùn)行這個(gè)例子,只需放在一個(gè)文件中并運(yùn)行它。你可以用ctrl-c終止它。我們可以使用curl命令測(cè)試它,可用在大多數(shù)*nix平臺(tái):
$ curl -D - http://localhost:8000/
HTTP/1.1 200 OK
Connection: keep-alive
Transfer-Encoding: chunked
hi
讓我們一點(diǎn)點(diǎn)來(lái)反饋服務(wù)器上發(fā)生的事情。這時(shí),我們可以友好的對(duì)待用戶并提供他們一些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
再次嘗試訪問(wèn)它,但是這一次使用不同的URL路徑,比如http://localhost:8000/coffee
。你會(huì)看到這樣的服務(wù)器控制臺(tái):
$ coffee http-server.coffee
GET /
GET /coffee
GET /user/1337
假如我們的網(wǎng)絡(luò)服務(wù)器能夠保存一些數(shù)據(jù)會(huì)怎么樣?我們將在通過(guò)GET方法請(qǐng)求檢索的元素中設(shè)法想出一個(gè)簡(jiǎn)單的鍵值存儲(chǔ)。并提供一個(gè)關(guān)鍵路徑,服務(wù)器將請(qǐng)求返回相應(yīng)的值,如果不存在則返回404錯(cuò)誤。
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會(huì)怎么樣?同時(shí),我們的存儲(chǔ)檢索過(guò)程也可以用一點(diǎn)重構(gòu)——一些異常的拋出&處理怎么樣? 來(lái)看看我們能想出什么:
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
這個(gè)服務(wù)器仍然會(huì)返回一個(gè)匹配給定鍵的值,如果不存在則返回404錯(cuò)誤。但它根據(jù)標(biāo)頭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
我們的最后一步是提供客戶端存儲(chǔ)數(shù)據(jù)的能力。我們將通過(guò)監(jiān)聽POST請(qǐng)求來(lái)保持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
在一個(gè)POST請(qǐng)求中注意數(shù)據(jù)是如何接收的。通過(guò)在“數(shù)據(jù)”和“結(jié)束”請(qǐng)求對(duì)象的事件中附上一些處理程序,我們最終能夠從客戶端緩沖和保存數(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一個(gè)函數(shù) (request,response) - >…… 它將返回一個(gè)服務(wù)器對(duì)象,我們可以用它來(lái)監(jiān)聽一個(gè)端口。讓服務(wù)器與request和response對(duì)象交互。使用server.listen 8000監(jiān)聽端口8000。
在這個(gè)問(wèn)題上的API和整體信息,參考node.js http和https文檔頁(yè)面。此外,HTTP spec可能派上用場(chǎng)。
在服務(wù)器和開發(fā)人員之間創(chuàng)建一個(gè)層,允許開發(fā)人員做類似的事情:
server = layer.createServer
'GET /': (req, res) ->
...
'GET /page': (req, res) ->
...
'PUT /image': (req, res) ->
...
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: