1. 程式人生 > >深入學習HTTP(一)

深入學習HTTP(一)

HTTP1.1

HTTP請求

server.on('request', function(req, res){
    console.log(req.url);
    console.log(req.headers);
    res.end("hello");

});

回撥函式中,第一個引數是IncomingMessage物件,用於讀取客戶端請求流中的資料,因此,當從客戶端請求流中讀取到新的資料時觸發data事件,當讀取完畢時,觸發end事件。

IncomingMessage物件的一些重要屬性:

  • method:
  • url
  • headers
  • httpVersion
  • trailers
  • socket:該屬性值是服務端用於監聽客戶端請求的Socket物件

請求頭部

{ 
  host: 'localhost:8080',
  connection: 'keep-alive',
  'cache-control': 'max-age=0',
  'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
  'upgrade-insecure-requests': '1',
  accept: 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8'
, 'accept-encoding': 'gzip, deflate, br',
}
  • connection: ‘keep-alive’

    HTTP1.1新增的長連線支援,只要客戶端發出的請求或者服務端發出的響應的頭部中包含此欄位。

  • ‘cache-control’: ‘max-age=0’

響應頭部

server.on('request', function(req, res){
    console.log(url.parse(req.url));
    console.log("headers: %j" ,req.headers);
    console.log('httpVersion: '
+ req.httpVersion); res.end(querystr); });
  • res是一個http.ServerResponse物件
res.writeHead(statusCode:[readsonPhrase],[headers])
  • statusCode 狀態碼
  • readsonPhrase 狀態碼資訊描述
  • headers 頭部
server.on('request', function(req, res){
    if(req.url != "/favicon.ico") {
        res.writeHead(200,{
            "Content-Type":"text/plain",
            "Access-Control-Allow-Origin":"http://localhost",
            "Content-encoding":"utf-8",
            "Set-Cookie":["type=ninja","language=javascript"]
        });
        res.write("你好");
    }
    res.end();

});

這裡寫圖片描述

客戶端請求

var http = require('http');
options = {
    hostname:"localhost",
    port:8080,
    path:"/api",
    method:"GET",
    auth:"user:pass"
};

var req = http.request(options, function(res) {
    console.log(res.statusCode);
    console.log(JSON.stringify(res.headers));
    res.on("data", function(chunk) {
        console.log(chunk.toString());
    });
});

req.on("socket", function(socket) {
    console.log('拿到socket');
    socket.setTimeout(1000, function() {
        req.abort();
    });
});

req.on("error", function(err) {
    console.log('出錯啦' + err.code);
})
req.end();

製作代理伺服器

var http = require("http");
var url = require("url");
var server = http.createServer(function(sreq, sres) {
    var url_parts = url.parse(sreq.url);
    var options = {
        host:"www.amazon.cn",
        port:80,
        path:url_parts.pathname,
        headers:sreq.headers
    };

    var creq = http.get(options, function(cres) {
        sres.writeHead(cres.statusCode, cres.headers);
        cres.pipe(sres);
    });
    sreq.pipe(creq);
});
server.on("connection", function(socket) {
    console.log('連線已建立');
});
server.on("error", function(err) {
    console.log(err);
});

server.listen(8000,"127.0.0.1");

伺服器超時

var timeout = 6 * 1000;
server.setTimeout(timeout, function(socket) {
    console.log('伺服器超時');
    console.log(socket);
});
  • socket
Socket {
  connecting: false,
  _hadError: false,
  _handle:
   TCP {
     reading: true,
     owner: [Circular],
     onread: [Function: onread],
     onconnection: null,
     writeQueueSize: 0,
     _consumed: true },
  _parent: null,
  _host: null,
  _readableState:
   ReadableState {
     objectMode: false,
     highWaterMark: 16384,
     buffer: BufferList { head: null, tail: null, length: 0 },
     length: 0,
     pipes: null,
     pipesCount: 0,
     flowing: true,
     ended: false,
     endEmitted: false,
     reading: true,
     sync: false,
     needReadable: true,
     emittedReadable: false,
     readableListening: false,
     resumeScheduled: false,
     destroyed: false,
     defaultEncoding: 'utf8',
     awaitDrain: 0,
     readingMore: false,
     decoder: null,
     encoding: null },
  readable: true,
  domain: null,
  _events:
   { end: [ [Object], [Function: bound socketOnEnd] ],
     finish: [Function: onSocketFinish],
     _socketEnd: [Function: onSocketEnd],
     drain: [ [Function: ondrain], [Function: bound socketOnDrain] ],
     timeout: [Function: socketOnTimeout],
     data: [Function: bound socketOnData],
     error: [Function: socketOnError],
     close: [Function: bound socketOnClose],
     resume: [Function: onSocketResume],
     pause: [Function: onSocketPause] },
  _eventsCount: 10,
  _maxListeners: undefined,
  _writableState:
   WritableState {
     objectMode: false,
     highWaterMark: 16384,
     finalCalled: false,
     needDrain: false,
     ending: false,
     ended: false,
     finished: false,
     destroyed: false,
     decodeStrings: false,
     defaultEncoding: 'utf8',
     length: 0,
     writing: false,
     corked: 0,
     sync: false,
     bufferProcessing: false,
     onwrite: [Function: bound onwrite],
     writecb: null,
     writelen: 0,
     bufferedRequest: null,
     lastBufferedRequest: null,
     pendingcb: 0,
     prefinished: false,
     errorEmitted: false,
     bufferedRequestCount: 0,
     corkedRequestsFree:
      { next: null,
        entry: null,
        finish: [Function: bound onCorkedFinish] } },
  writable: true,
  allowHalfOpen: true,
  _bytesDispatched: 208,
  _sockname: null,
  _pendingData: null,
  _pendingEncoding: '',
  server:
   Server {
     domain: null,
     _events:
      { connection: [Array],
        listening: [Function],
        request: [Function],
        error: [Function],
        timeout: [Function] },
     _eventsCount: 5,
     _maxListeners: undefined,
     _connections: 4,
     _handle:
      TCP {
        reading: false,
        owner: [Circular],
        onread: null,
        onconnection: [Function: onconnection],
        writeQueueSize: 0 },
     _usingSlaves: false,
     _slaves: [],
     _unref: false,
     allowHalfOpen: true,
     pauseOnConnect: false,
     httpAllowHalfOpen: false,
     timeout: 6000,
     keepAliveTimeout: 5000,
     _pendingResponseData: 0,
     maxHeadersCount: null,
     _connectionKey: '4:127.0.0.1:8080',
     [Symbol(asyncId)]: 7 },
  _server:
   Server {
     domain: null,
     _events:
      { connection: [Array],
        listening: [Function],
        request: [Function],
        error: [Function],
        timeout: [Function] },
     _eventsCount: 5,
     _maxListeners: undefined,
     _connections: 4,
     _handle:
      TCP {
        reading: false,
        owner: [Circular],
        onread: null,
        onconnection: [Function: onconnection],
        writeQueueSize: 0 },
     _usingSlaves: false,
     _slaves: [],
     _unref: false,
     allowHalfOpen: true,
     pauseOnConnect: false,
     httpAllowHalfOpen: false,
     timeout: 6000,
     keepAliveTimeout: 5000,
     _pendingResponseData: 0,
     maxHeadersCount: null,
     _connectionKey: '4:127.0.0.1:8080',
     [Symbol(asyncId)]: 7 },
  _idleTimeout: 5000,
  _idleNext: null,
  _idlePrev: null,
  _idleStart: 17735,
  _destroyed: false,
  parser:
   HTTPParser {
     '0': [Function: parserOnHeaders],
     '1': [Function: parserOnHeadersComplete],
     '2': [Function: parserOnBody],
     '3': [Function: parserOnMessageComplete],
     '4': [Function: bound onParserExecute],
     _headers: [],
     _url: '',
     _consumed: true,
     socket: [Circular],
     incoming:
      IncomingMessage {
        _readableState: [Object],
        readable: false,
        domain: null,
        _events: {},
        _eventsCount: 0,
        _maxListeners: undefined,
        socket: [Circular],
        connection: [Circular],
        httpVersionMajor: 1,
        httpVersionMinor: 1,
        httpVersion: '1.1',
        complete: true,
        headers: [Object],
        rawHeaders: [Array],
        trailers: {},
        rawTrailers: [],
        upgrade: false,
        url: '/favicon.ico',
        method: 'GET',
        statusCode: null,
        statusMessage: null,
        client: [Circular],
        _consuming: true,
        _dumped: true,
        read: [Function] },
     outgoing: null,
     maxHeaderPairs: 2000,
     onIncoming: [Function: bound parserOnIncoming] },
  on: [Function: socketOnWrap],
  _paused: false,
  read: [Function],
  _consuming: true,
  _httpMessage: null,
  _called: true,
  [Symbol(asyncId)]: 10,
  [Symbol(bytesRead)]: 0,
  [Symbol(asyncId)]: 12,
  [Symbol(triggerAsyncId)]: 10 }