<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                ## 問題 你想到網絡中搭建一個HTTP服務器。在本菜譜中,我們從最簡單的服務器到一個功能完好的鍵值對存儲服務器,一步步地學習創建HTTP服務器。 ## 方法 處于自私的目的,我們將使用[node.js](http://nodejs.org/)的HTTP類庫,使用CoffeeScript創建最簡單的服務器。 ### 問候 ‘hi\n’ 我們可以從引入node.js的HTTP模塊開始。該模塊包含了`createServer`,這是一個簡單的請求處理器,返回一個HTTP服務器。我們讓這個服務器監聽在一個TCP端口上。 ~~~ http = require 'http' server = http.createServer (req, res) -> res.end 'hi\n' server.listen 8000 ~~~ 把這些代碼放在一個文件中運行,就可以執行這個示例。你可以使用`Ctrl-C`來關掉它。我們可以使用`curl`命令測試,在絕大多數的*nix平臺上都可以運行: ~~~ $ curl -D - http://localhost:8000/ HTTP/1.1 200 OK Connection: keep-alive Transfer-Encoding: chunked hi ~~~ ### 接下來呢? 讓我們弄點反饋,看看我們服務器上發生了什么。同時,我們還對我們用戶更友好一點,并為他們提供一些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`。你可以在服務器上看到如下的調試信息: ~~~ $ coffee http-server.coffee GET / GET /coffee GET /user/1337 ~~~ ### GET點啥 服務器上放點數據?我們就放一個簡單的鍵值存儲吧,鍵值元素可以通過GET請求獲取。把key放到請求路徑中,服務器就會返回相應的value &mdash,如果不錯在的話就返回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 ~~~ 我們可以找幾個URLs嘗試一下,看看他是如何返回的: ~~~ $ 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 ~~~ ### 加上headers 承認吧,`text/plain`挺無聊的。我們要不使用`application/json`或者`text/xml`等試試看?并且,我們的讀取存儲的過程是不是應該重構一下&mdash,添加點異常處理?讓我們看看能產生什么效果: ~~~ 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 ~~~ 服務器返回的還是key能夠匹配到的值,無匹配的話就返回404。但是它根據`Accept`頭,把返回值格式化成了JSON或者XML。自己試試看: ~~~ $ 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 ~~~ ### 你必須讓他們有恢復的能力 在我們冒險旅行的上一步,給我們的客戶端提供了存儲數據的能力。我們會保證我們是RESTfull的,提供對POST請求的監聽。 ~~~ 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請求中的數據的。聽過給請求對象的`'data'`和`'end'`事件綁定處理器來實現。我們可以把來來自客戶端的數據暫存或者最終存儲到`store`中。 ~~~ $ 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"} ~~~ ## Discussion ## 討論 給`http.createServer`傳遞一個型如`(request, respone) ->...`這樣的函數,它就會返回一個server對象,我們可以使用這個server對象監聽某個端口。與`request`和`response`對象交互,實現server的行為。使用`server.listen 8000`來監聽8000端口。 關于這個主題的API或者更為詳細的信息,請參考[http](http://nodejs.org/docs/latest/api/http.html)以及[https](http://nodejs.org/docs/latest/api/https.html)這兩頁文檔。而且[HTTP spec](http://www.ietf.org/rfc/rfc2616.txt)遲早也會用到。 ### 練習 * 在服務器和開發者之間建立一個layer(layer),允許開發者可以像下面這樣寫: ~~~ server = layer.createServer 'GET /': (req, res) -> ... 'GET /page': (req, res) -> ... 'PUT /image': (req, res) -> ... ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看