nodejs-http模塊

************************************************************
*************************http模塊***************************
************************************************************
一绒窑、服務(wù)端
        var http = require('http');
        var fs = require('fs');
        var url = require('url');
        // 創(chuàng)建服務(wù)器
        http.createServer( function (request, response) {  
           // 解析請求瞳别,包括文件名
           var pathname = url.parse(request.url).pathname;
           
           // 輸出請求的文件名
           console.log("Request for " + pathname + " received.");
           
           // 從文件系統(tǒng)中讀取請求的文件內(nèi)容
           fs.readFile(pathname.substr(1), function (err, data) {
              if (err) {
                 console.log(err);
                 // HTTP 狀態(tài)碼: 404 : NOT FOUND
                 // Content Type: text/plain
                 response.writeHead(404, {'Content-Type': 'text/html'});
              }else{             
                 // HTTP 狀態(tài)碼: 200 : OK
                 // Content Type: text/plain
                 response.writeHead(200, {'Content-Type': 'text/html'});    
                 
                 // 響應(yīng)文件內(nèi)容
                 response.write(data.toString());       
              }
              //  發(fā)送響應(yīng)數(shù)據(jù)
              response.end();
           });   
        }).listen(8081);

        // 控制臺會輸出以下信息
        console.log('Server running at http://127.0.0.1:8081/');

二、客戶端
        var http = require('http');
        // 用于請求的選項(xiàng)
        var options = {
           host: 'localhost',
           port: '8081',
           path: '/index.htm'  
        };

        // 處理響應(yīng)的回調(diào)函數(shù)
        var callback = function(response){
           // 不斷更新數(shù)據(jù)
           var body = '';
           response.on('data', function(data) {
              body += data;
           });
           
           response.on('end', function() {
              // 數(shù)據(jù)接收完成
              console.log(body);
           });
        }
        // 向服務(wù)端發(fā)送請求
        var req = http.request(options, callback);
        req.end();
三、API
HTTP
     http.STATUS_CODES
     http.createServer([requestListener])
     http.createClient([port], [host])
     Class: http.Server
     事件 : 'request'
     事件: 'connection'
     事件: 'close'
     事件: 'checkContinue'
     事件: 'connect'
     事件: 'upgrade'
     事件: 'clientError'
     server.listen(port, [hostname], [backlog], [callback])
     server.listen(path, [callback])
     server.listen(handle, [callback])
     server.close([callback])
     server.maxHeadersCount
     server.setTimeout(msecs, callback)
     server.timeout
     Class: http.ServerResponse
         事件: 'close'
         response.writeContinue()
         *response.writeHead(statusCode, [reasonPhrase], [headers])
                    例子:req是http.IncomingMessage實(shí)例 res是http.ServerResponse實(shí)例
                        var server = http.createServer(function(req,res){
                          res.writeHeader(200,{
                              'Content-Type' : 'text/plain;charset=utf-8'  // 添加charset=utf-8
                          }) ;
                          res.end("Hello,大熊!") ;
                          }) ;
         response.setTimeout(msecs, callback)
         response.statusCode
         *response.setHeader(name, value)
         response.headersSent
         response.sendDate
         *response.getHeader(name)
         response.removeHeader(name)
         *response.write(chunk, [encoding])
         response.addTrailers(headers)
         *response.end([data], [encoding])
         http.request(options, callback)
         http.get(options, callback)
     Class: http.Agent
         new Agent([options])
         agent.maxSockets
         agent.maxFreeSockets
         agent.sockets
         agent.freeSockets
         agent.requests
         agent.destroy()
         agent.getName(options)
         http.globalAgent
     Class: http.ClientRequest
         事件 'response'
         事件: 'socket'
         事件: 'connect'
         事件: 'upgrade'
         事件: 'continue'
         request.write(chunk, [encoding])
         request.end([data], [encoding])
         request.abort()
         request.setTimeout(timeout, [callback])
         request.setNoDelay([noDelay])
         request.setSocketKeepAlive([enable], [initialDelay])
     http.IncomingMessage
         事件: 'close'
         message.httpVersion
         message.headers
         message.rawHeaders
         message.trailers
         message.rawTrailers
         message.setTimeout(msecs, callback)
         message.method
         message.url
         message.statusCode
         message.socket
                  //例子
                  http.createServer(function (request, response) {
                  var body = [];
                  console.log(request.method) ;
                  console.log(request.headers) ;
                  request.on('data', function (chunk) {
                      body.push(chunk);
                  }) ;
                  request.on('end', function () {
                      body = Buffer.concat(body) ;
                      console.log(body.toString()) ;
                  });
                  }).listen(8888) ;
                /*{ accept: 'text/html, application/xhtml+xml, image/jxr, */*',
                  'accept-language': 'zh-Hans-CN,zh-Hans;q=0.5',
                  'user-agent': 'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 10.0; WOW64; Trident/7.0)',
                  'accept-encoding': 'gzip, deflate',
                  host: 'localhost:8888',
                  connection: 'Keep-Alive' }*/

1.http頭格式
{ 'content-length': '123',
  'content-type': 'text/plain',
  'connection': 'keep-alive',
  'host': 'mysite.com',
  'accept': '*/*' }
2.Class: http.Agent
    (1)如果 HTTP KeepAlive的話,則會把當(dāng)前請求放入請求池,方便再利用
      Sockets 會從agent's pool 移除當(dāng)觸發(fā)'close' 或者 'agentRemove'事件
      如:
        http.get(options, (res) => {
          // Do stuff
        }).on('socket', (socket) => {
          socket.emit('agentRemove'); //釋放socket請求
        }); 
    (2)或者直接設(shè)置agent:false逗扒,就會直接釋放
        http.get({
          hostname: 'localhost',
          port: 80,
          path: '/',
          agent: false  // create a new agent just for this one request
        }, (res) => {
          // Do stuff with response
        })
     (3)new Agent([options]
            options <Object> 
                keepAlive <Boolean> 放入pool 可以被其他請求使用 Default = false
                keepAliveMsecs <Integer> 當(dāng)使用HTTP KeepAlive=true時使用,  Default = 1000. 
                maxSockets <Number>  sockets允許請求host的最大值. Default = Infinity.
                maxFreeSockets <Number> sockets請求的最大值.  keepAlive=true. Default = 256
          例子:
            const http = require('http');
            var keepAliveAgent = new http.Agent({ keepAlive: true });
            options.agent = keepAliveAgent;
            http.request(options, onResponseCallback);
     (4)agent.createConnection(options[, callback]) 回調(diào)(err, stream).

     (5)agent.destroy()
             關(guān)閉所有的當(dāng)前agent使用的socks請求,否則客戶端會很長時間才關(guān)閉請求
      (6)agent.freeSockets

     (7)欠橘?矩肩?agent.getName(options)
     (8)agent.maxFreeSockets
     (9)agent.maxSockets
     (10)agent.requests  還沒有分配給sockets的請求
     (11)agent.sockets   正在被agent使用的sockets數(shù)組

3.Class: http.ClientRequest 實(shí)現(xiàn)了 Writable Stream 接口
    (1)**http.request()返回,header已經(jīng)被設(shè)置好了
        默認(rèn)setHeader(name, value), getHeader(name), removeHeader(name) 
    (2)事件Event: 
        'abort'#aborted by the client觸發(fā)
            function () { }
        'checkExpectation'#
            function (request, response) { }
        'connect'#
            function (response, socket, head) { }

    (3)例子
            const http = require('http');
            const net = require('net');
            const url = require('url');

            // Create an HTTP tunneling proxy
            var proxy = http.createServer( (req, res) => {
              res.writeHead(200, {'Content-Type': 'text/plain'});
              res.end('okay');
            });
            proxy.on('connect', (req, cltSocket, head) => {
              // connect to an origin server
              var srvUrl = url.parse(`http://${req.url}`);
              var srvSocket = net.connect(srvUrl.port, srvUrl.hostname, () => {
                cltSocket.write('HTTP/1.1 200 Connection Established\r\n' +
                                'Proxy-agent: Node.js-Proxy\r\n' +
                                '\r\n');
                srvSocket.write(head);
                srvSocket.pipe(cltSocket);
                cltSocket.pipe(srvSocket);
              });
            });

            // now that proxy is running
            proxy.listen(1337, '127.0.0.1', () => {

              // make a request to a tunneling proxy
              var options = {
                port: 1337,
                hostname: '127.0.0.1',
                method: 'CONNECT',
                path: 'www.google.com:80'
              };

              var req = http.request(options);
              req.end();
              //監(jiān)聽connect事件
              req.on('connect', (res, socket, head) => {
                    console.log('got connected!');
                    // make a request over an HTTP tunnel
                    socket.write('GET / HTTP/1.1\r\n' +
                                 'Host: www.google.com:80\r\n' +
                                 'Connection: close\r\n' +
                                 '\r\n');
                    socket.on('data', (chunk) => {
                      console.log(chunk.toString());
                    });
                    socket.on('end', () => {
                      proxy.close();
                });
              });
            });

    (4)Event: 'continue'#
        function () { }
    (5)Event: 'response'#
        function (response) { }
    (6)Event: 'socket'#
        function (socket) { }
    (7)Event: 'upgrade'#
        function (response, socket, head) { }

    (8)例子
            const http = require('http');
            // Create an HTTP server
            var srv = http.createServer( (req, res) => {
              res.writeHead(200, {'Content-Type': 'text/plain'});
              res.end('okay');
            });
            srv.on('upgrade', (req, socket, head) => {
              socket.write('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' +
                           'Upgrade: WebSocket\r\n' +
                           'Connection: Upgrade\r\n' +
                           '\r\n');

              socket.pipe(socket); // echo back
            });

            // now that server is running
            srv.listen(1337, '127.0.0.1', () => {

              // make a request
              var options = {
                port: 1337,
                hostname: '127.0.0.1',
                headers: {
                  'Connection': 'Upgrade',
                  'Upgrade': 'websocket'
                }
              };

              var req = http.request(options);
              req.end();

              req.on('upgrade', (res, socket, upgradeHead) => {
                console.log('got upgraded!');
                socket.end();
                process.exit(0);
              });
            });
        (9)request.abort()
        (10)request.end([data][, encoding][, callback])
        (11)request.flushHeaders()
        (12)request.setNoDelay([noDelay])
        (13)request.setSocketKeepAlive([enable][, initialDelay])
        (14)request.setTimeout(timeout[, callback])
        (15)request.write(chunk[, encoding][, callback])


4.Class: http.Server
    (1)Event: 'checkContinue'#
        function (request, response) { }
    (2)Event: 'clientError'#
        function (exception, socket) { }
    (3)Event: 'close'#
        function () { }
    (4)Event: 'connect'#
        function (request, socket, head) { }
    (5)Event: 'connection'#
        function (socket) { }
    (6)Event: 'request'#
        function (request, response) { }
    (7)Event: 'upgrade'#
        function (request, socket, head) { }
    (8)server.close([callback])
    (9)server.listen(handle[, callback])
    (10)server.listen(path[, callback])
    (11)server.listen(port[, hostname][, backlog][, callback])
    (12)server.maxHeadersCount最大頭數(shù)目
    (13)server.setTimeout(msecs, callback)  Returns server.
        設(shè)置請求超時事件默認(rèn)2分鐘
   (14)server.timeout <Number> Default = 120000 (2 minutes)

 5.Class: http.ServerResponse 由server創(chuàng)建,非用戶創(chuàng)建
    (1)Event: 'close'#
        function () { }
    (2)Event: 'finish'# //此事件是最后一個被觸發(fā)的
        function () { }
    (3)response.addTrailers(headers) 注意http1.0廢棄
        如:response.writeHead(200, { 'Content-Type': 'text/plain',
                          'Trailer': 'Content-MD5' });
            response.write(fileData);
            response.addTrailers({'Content-MD5': '7895bf4b8828b55ceaf47747b4bca667'});
            response.end();
    (4)response.end([data][, encoding][, callback])
    (5)response.finished
       開始時候?yàn)閒alse. 當(dāng)調(diào)用完response.end(), 就變?yōu)榱?true.
     (6)response.getHeader(name) 
        如:var contentType = response.getHeader('content-type');
    (7)response.removeHeader(name)
        如:response.removeHeader('Content-Encoding');
    (8)response.sendDate 默認(rèn) true.Date header自動添加
    (9)response.setHeader(name, value)
            如:response.setHeader('Content-Type', 'text/html');
                response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']);
    (10)res.writeHead優(yōu)先執(zhí)行
        // returns content-type = text/plain
        const server = http.createServer((req,res) => {
          res.setHeader('Content-Type', 'text/html');
          res.setHeader('X-Foo', 'bar');
          res.writeHead(200, {'Content-Type': 'text/plain'});
          res.end('ok');
        });
    (11)response.setTimeout(msecs, callback) Returns response.
    (12)response.statusCode
    (13)response.statusMessage = 'Not found';
    (14)response.write(chunk[, encoding][, callback])
6.Class: http.IncomingMessage
        (1)原理
                由http.Server or http.ClientRequest創(chuàng)建黍檩,作為'request' and 'response' event 第一個參數(shù)
                用來獲得respose的status, headers and data.實(shí)現(xiàn)了Readable Stream接口
        (2)包括以下事件
            Event: 'close'#
            function () { }
        
        (3)message.headers
            // Prints something like:
            //
            // { 'user-agent': 'curl/7.22.0',
            //   host: '127.0.0.1:8000',
            //   accept: '*/*' }
            console.log(request.headers);

        (4)message.httpVersion  '1.1' or '1.0'.
        (5)message.method  'GET', 'DELETE'.

        (6)message.rawHeaders
            // Prints something like:
            //
            // [ 'user-agent',
            //   'this is invalid because there can be only one',
            //   'User-Agent',
            //   'curl/7.22.0',
            //   'Host',
            //   '127.0.0.1:8000',
            //   'ACCEPT',
            //   '*/*' ]
            console.log(request.rawHeaders);

        (7)http.get(options[, callback])
                http.get('http://www.google.com/index.html', (res) => {
                  console.log(`Got response: ${res.statusCode}`);
                  // consume response body
                  res.resume();
                }).on('error', (e) => {
                  console.log(`Got error: ${e.message}`);
                });


        (8)http.request(options[, callback])
            var postData = querystring.stringify({
              'msg' : 'Hello World!'
            });

            var options = {
              hostname: 'www.google.com',
              port: 80,
              path: '/upload',
              method: 'POST',
              headers: {
                'Content-Type': 'application/x-www-form-urlencoded',
                'Content-Length': postData.length
              }
            };

            var req = http.request(options, (res) => {
              console.log(`STATUS: ${res.statusCode}`);
              console.log(`HEADERS: ${JSON.stringify(res.headers)}`);
              res.setEncoding('utf8');
              res.on('data', (chunk) => {
                console.log(`BODY: ${chunk}`);
              });
              res.on('end', () => {
                console.log('No more data in response.')
              })
            });

            req.on('error', (e) => {
              console.log(`problem with request: ${e.message}`);
            });

            // write data to request body
            req.write(postData);
            req.end();

url解析

'use strict';
var url = require('url');
console.log(url.parse('http://user:pass@host.com:8080/path/to/file?query=string#hash'));
Url {
  protocol: 'http:',
  slashes: true,
  auth: 'user:pass',
  host: 'host.com:8080',
  port: '8080',
  hostname: 'host.com',
  hash: '#hash',
  search: '?query=string',
  query: 'query=string',
  pathname: '/path/to/file',
  path: '/path/to/file?query=string',
  href: 'http://user:pass@host.com:8080/path/to/file?query=string#hash' }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末咙鞍,一起剝皮案震驚了整個濱河市程储,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖湿颅,帶你破解...
    沈念sama閱讀 211,817評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弥咪,死亡現(xiàn)場離奇詭異垮兑,居然都是意外死亡禾进,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,329評論 3 385
  • 文/潘曉璐 我一進(jìn)店門殿怜,熙熙樓的掌柜王于貴愁眉苦臉地迎上來典蝌,“玉大人,你說我怎么就攤上這事头谜】ハ疲” “怎么了?”我有些...
    開封第一講書人閱讀 157,354評論 0 348
  • 文/不壞的土叔 我叫張陵柱告,是天一觀的道長截驮。 經(jīng)常有香客問我,道長际度,這世上最難降的妖魔是什么侧纯? 我笑而不...
    開封第一講書人閱讀 56,498評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮甲脏,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘妹笆。我一直安慰自己块请,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,600評論 6 386
  • 文/花漫 我一把揭開白布拳缠。 她就那樣靜靜地躺著墩新,像睡著了一般。 火紅的嫁衣襯著肌膚如雪窟坐。 梳的紋絲不亂的頭發(fā)上海渊,一...
    開封第一講書人閱讀 49,829評論 1 290
  • 那天,我揣著相機(jī)與錄音哲鸳,去河邊找鬼臣疑。 笑死,一個胖子當(dāng)著我的面吹牛徙菠,可吹牛的內(nèi)容都是我干的讯沈。 我是一名探鬼主播,決...
    沈念sama閱讀 38,979評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼婿奔,長吁一口氣:“原來是場噩夢啊……” “哼缺狠!你這毒婦竟也來了问慎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,722評論 0 266
  • 序言:老撾萬榮一對情侶失蹤挤茄,失蹤者是張志新(化名)和其女友劉穎如叼,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體穷劈,經(jīng)...
    沈念sama閱讀 44,189評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡笼恰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,519評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了囚衔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片挖腰。...
    茶點(diǎn)故事閱讀 38,654評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖练湿,靈堂內(nèi)的尸體忽然破棺而出猴仑,到底是詐尸還是另有隱情,我是刑警寧澤肥哎,帶...
    沈念sama閱讀 34,329評論 4 330
  • 正文 年R本政府宣布辽俗,位于F島的核電站,受9級特大地震影響篡诽,放射性物質(zhì)發(fā)生泄漏崖飘。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,940評論 3 313
  • 文/蒙蒙 一杈女、第九天 我趴在偏房一處隱蔽的房頂上張望朱浴。 院中可真熱鬧,春花似錦达椰、人聲如沸翰蠢。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,762評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽梁沧。三九已至,卻和暖如春蝇裤,著一層夾襖步出監(jiān)牢的瞬間廷支,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,993評論 1 266
  • 我被黑心中介騙來泰國打工栓辜, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恋拍,地道東北人。 一個月前我還...
    沈念sama閱讀 46,382評論 2 360
  • 正文 我出身青樓啃憎,卻偏偏與公主長得像芝囤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,543評論 2 349

推薦閱讀更多精彩內(nèi)容