nodejs-http模块

************************************************************
*************************http模块***************************
************************************************************
一、服务端
        var http = require('http');
        var fs = require('fs');
        var url = require('url');
        // 创建服务器
        http.createServer( function (request, response) {  
           // 解析请求,包括文件名
           var pathname = url.parse(request.url).pathname;
           
           // 输出请求的文件名
           console.log("Request for " + pathname + " received.");
           
           // 从文件系统中读取请求的文件内容
           fs.readFile(pathname.substr(1), function (err, data) {
              if (err) {
                 console.log(err);
                 // HTTP 状态码: 404 : NOT FOUND
                 // Content Type: text/plain
                 response.writeHead(404, {'Content-Type': 'text/html'});
              }else{             
                 // HTTP 状态码: 200 : OK
                 // Content Type: text/plain
                 response.writeHead(200, {'Content-Type': 'text/html'});    
                 
                 // 响应文件内容
                 response.write(data.toString());       
              }
              //  发送响应数据
              response.end();
           });   
        }).listen(8081);

        // 控制台会输出以下信息
        console.log('Server running at http://127.0.0.1:8081/');

二、客户端
        var http = require('http');
        // 用于请求的选项
        var options = {
           host: 'localhost',
           port: '8081',
           path: '/index.htm'  
        };

        // 处理响应的回调函数
        var callback = function(response){
           // 不断更新数据
           var body = '';
           response.on('data', function(data) {
              body += data;
           });
           
           response.on('end', function() {
              // 数据接收完成
              console.log(body);
           });
        }
        // 向服务端发送请求
        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实例 res是http.ServerResponse实例
                        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的话,则会把当前请求放入请求池,方便再利用
      Sockets 会从agent's pool 移除当触发'close' 或者 'agentRemove'事件
      如:
        http.get(options, (res) => {
          // Do stuff
        }).on('socket', (socket) => {
          socket.emit('agentRemove'); //释放socket请求
        }); 
    (2)或者直接设置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> 当使用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]) 回调(err, stream).

     (5)agent.destroy()
             关闭所有的当前agent使用的socks请求,否则客户端会很长时间才关闭请求
      (6)agent.freeSockets

     (7)??agent.getName(options)
     (8)agent.maxFreeSockets
     (9)agent.maxSockets
     (10)agent.requests  还没有分配给sockets的请求
     (11)agent.sockets   正在被agent使用的sockets数组

3.Class: http.ClientRequest 实现了 Writable Stream 接口
    (1)**http.request()返回,header已经被设置好了
        默认setHeader(name, value), getHeader(name), removeHeader(name) 
    (2)事件Event: 
        'abort'#aborted by the client触发
            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();
              //监听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最大头数目
    (13)server.setTimeout(msecs, callback)  Returns server.
        设置请求超时事件默认2分钟
   (14)server.timeout <Number> Default = 120000 (2 minutes)

 5.Class: http.ServerResponse 由server创建,非用户创建
    (1)Event: 'close'#
        function () { }
    (2)Event: 'finish'# //此事件是最后一个被触发的
        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
       开始时候为false. 当调用完response.end(), 就变为了 true.
     (6)response.getHeader(name) 
        如:var contentType = response.getHeader('content-type');
    (7)response.removeHeader(name)
        如:response.removeHeader('Content-Encoding');
    (8)response.sendDate 默认 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优先执行
        // 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创建,作为'request' and 'response' event 第一个参数
                用来获得respose的status, headers and data.实现了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' }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,670评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,928评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,926评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,238评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,112评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,138评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,545评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,232评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,496评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,596评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,369评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,226评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,600评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,906评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,185评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,516评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,721评论 2 335

推荐阅读更多精彩内容