幾行代碼搞定html
var http = require('http'); var requestListener = function(req, res){ res.end('ok'); }; var server = http.createServer(requestListener); // var server = new http.Server(requestListener); 跟上面是等價的 server.listen(3000);
var http = require('http'); var server = http.createServer(function(req, res){ console.log('客戶端請求url:' + req.url); console.log('http版本:' + req.httpVersion); console.log('http請求方法:' + req.method); res.end('ok'); }); server.listen(3000);
效果以下:node
客戶端請求url:/hello
http版本:1.1
http請求方法:GET
http headers:{"host":"127.0.0.1:3000","connection":"keep-alive","cache-control":"max-age=0","upgrade-insecure-requests":"1","user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.71 Safari/537.36","accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8","accept-encoding":"gzip, deflate, sdch, br","accept-language":"zh-CN,zh;q=0.8,en;q=0.6,zh-TW;q=0.4"}
var http = require('http'); var url = require('url'); var querystring = require('querystring'); var server = http.createServer(function(req, res){ var urlObj = url.parse(req.url); var query = urlObj.query; var queryObj = querystring.parse(query); console.log( JSON.stringify(queryObj) ); res.end('ok'); }); server.listen(3000);
運行以下命令git
curl http://127.0.0.1:3000/hello\?nick\=chyingp\&hello\=world
服務端輸出以下github
{"nick":"chyingp","hello":"world"}
代碼以下web
var http = require('http'); var url = require('url'); var querystring = require('querystring'); var server = http.createServer(function(req, res){ var body = ''; req.on('data', function(thunk){ body += thunk; }); req.on('end', function(){ console.log( 'post body is: ' + body ); res.end('ok'); }); }); server.listen(3000);
經過curl構造極簡post請求shell
curl -d 'nick=casper&hello=world' http://127.0.0.1:3000
服務端打印以下。注意,在post請求中,不一樣的Content-type
,post body有不小差別,感興趣的同窗能夠本身試下。windows
post body is: nick=casper&hello=world
好比本例中的post請求,HTTP報文大概以下服務器
POST / HTTP/1.1 Host: 127.0.0.1:3000 Content-Type: application/x-www-form-urlencoded Cache-Control: no-cache nick=casper&hello=world
首先,咱們來看下有哪些事件網絡
checkContinue、checkExpectation、clientError、close、connect、connection、request、upgradeapp
var http = require('http'); var PORT = 3000; var noop = function(){}; var svr = http.createServer(noop); var anotherSvr = http.createServer(noop); anotherSvr.on('error', function(e){ console.error('出錯啦!' + e.message); }); svr.listen(PORT, function(){ anotherSvr.listen(PORT); });
運行代碼,輸出以下
出錯啦!listen EADDRINUSE :::3000
二者差異很是大,雖然字眼看着有點像。
大部分時候都不會用到,除非你要開發HTTP代理。當客戶端發起 connect 請求時觸發(注意繞過了 requestListener)
var http = require('http'); var PORT = 3000; var server = http.createServer(function(req, res){ res.end('ok'); }); // 注意:發起connect請求的例子在 ./httpServerEventConnectClient.js 裏 server.on('connect', function(req, socket, head){ console.log('connect事件觸發'); socket.end(); // 反正我就只想舉個例子,沒打算正經處理。。。 }); server.listen(PORT);
當有新的鏈接到來時觸發。那跟 connection 有什麼區別呢?
好了,keep-alive
閃亮登場!在持久化鏈接的狀況下,多個 request 可能對應的是 一個 connection。
先來看下沒有keep-alive
的場景
var http = require('http'); var PORT = 3000; var requestIndex = 0; var connectionIndex = 0; var server = http.createServer(function(req, res){ res.end('ok'); }); server.on('request', function(req, res){ requestIndex++; console.log('request event: 第'+ requestIndex +'個請求!'); }); server.on('connection', function(req, res){ connectionIndex++; console.log('connection event: 第'+ connectionIndex +'個請求!'); }); server.listen(PORT);
經過curl連續發送3個請求,看下效果
for i in `seq 1 3`; do curl http://127.0.0.1:3000; done
服務端輸出以下
connection event: 第1個請求!
request event: 第1個請求!
connection event: 第2個請求!
request event: 第2個請求!
connection event: 第3個請求!
request event: 第3個請求!
而後,再來看下有keep-alive
的場景。用 postman 構造包含 keep-alive 的請求,最終的HTTP請求報文以下
GET / HTTP/1.1 Host: 127.0.0.1:3000 Connection: keep-alive Cache-Control: no-cache Postman-Token: 6027fda7-f936-d3ac-e54f-dafcbf5e58ff
連續發送3個請求,服務端打印日誌以下
connection event: 第1個請求!
request event: 第1個請求!
request event: 第2個請求!
request event: 第3個請求!
關閉服務器。其實就是 (new net.Server()).close(),中止接受新的鏈接。 已經鏈接上的請求會繼續處理,當全部鏈接結束的時候,server 正式關閉,並拋出 close 事件。 通常提供了callback,就不用監聽close; 監聽了close,就不用添加callback。
其實除了 server.listen(PORT) 這種監聽方式外,還有如下幾種相對不那麼經常使用的監聽方式。用到的時候看看文檔就好了。
server.listen(handle[, callback]):監聽本地文件描述符(fd)(windows不支持),或者server,或者socket server.listen(path[, callback]):監聽本地socket,建立一個 UNIX socket server 。 server.listen([port][, hostname][, backlog][, callback])
設置網絡鏈接的超時時間。當超過 msecs 沒有響應時,網絡就會自動斷開。
若是傳了 callback,那麼當 timeout 發生時,就會將timeout的socket做爲參數傳給callback。
注意,通常狀況下超時的socket會自動銷燬。但當你傳了callback後,你就須要手動end或者destroy這個socket。
server.listening:是否在監聽鏈接 server.timeout:設置超時時間(毫秒),注意,修改這個值,只會對新創建的鏈接產生影響。此外,將timeout設置爲0,就會禁用自動超時行爲。(目測不推薦) server.maxHeadersCount:客戶端最多傳送的header數量,默認是1000,若是設置爲0,則沒有限制。(問題:若是超過1000怎麼辦??)