Node 深刻 HTTP 模塊

1. HTTP服務器 #

HTTP全稱是超文本傳輸協議,構建於TCP之上,屬於應用層協議。html

1.1 建立HTTP服務器

let server  = http.createServer([requestListener]);
server.on('request',requestListener);
複製代碼
  • requestListener 當服務器收到客戶端的鏈接後執行的處理
    • http.IncomingMessage 請求對象
    • http.ServerResponse對象 服務器端響應對象

1.2 啓動HTTP服務器

server.listen(port,[host],[backlog],[callback]);
server.on('listening',callback);
複製代碼
  • port 監聽的端口號
  • host 監聽的地址
  • backlog 指定位於等待隊列中的客戶端鏈接數
let http = require('http');
let server = http.createServer(function(req,res){
}).listen(8080,'127.0.0.1',function(){console.log('服務器端開始監聽!')});
複製代碼

1.3 關閉HTTP服務器

server.close();
server.on('close',function(){});
複製代碼
let http = require('http');
let server = http.createServer(function(req,res){
});
server.on('close',function(){
    console.log('服務器關閉');
});
server.listen(8080,'127.0.0.1',function(){
    console.log('服務器端開始監聽!')
    server.close();
});
複製代碼

1.4 監聽服務器錯誤

server.on('error',function(){
    if(e.code == 'EADDRINUSE'){
         console.log('端口號已經被佔用!); } }); 複製代碼

1.5 connection

let server = http.createServer(function(req,res){
});
server.on('connection',function(){
    console.log(客戶端鏈接已經創建);
});
複製代碼

1.6 setTimeout

設置超時時間,超時後不可再複用已經創建的鏈接,須要發請求須要從新創建鏈接。默認超時時間時2分鐘緩存

server.setTimeout(msecs,callback);
server.on('timeout',function(){
    console.log('鏈接已經超時');
});
複製代碼

1.7 獲取客戶端請求信息

  • request
    • method 請求的方法
    • url 請求的路徑
    • headers 請求頭對象
    • httpVersion 客戶端的http版本
    • socket 監聽客戶端請求的socket對象
      let http = require('http');
      let fs = require('fs');
      let server = http.createServer(function(req,res){
      if(req.url != '/favicon.ico'){
      let out = fs.createWriteStream(path.join(__dirname,'request.log'));
      out.write('method='+req.method);
      out.write('url='+req.url);
      out.write('headers='+JSON.stringify(req.headers));
      out.write('httpVersion='+req.httpVersion);
      }
      }).listen(8080,'127.0.0.1); 複製代碼
let http = require('http');
let fs = require('fs');
let server = http.createServer(function(req,res){
  let body = [];
  req.on('data',function(data){
    body.push(data);
  });
  req.on('end',function(){
      let result = Buffer.concat(body);
      console.log(result.toString());
  });
}).listen(8080,'127.0.0.1); 複製代碼

1.8 querystring

querystring模塊用來轉換URL字符串和URL中的查詢字符串bash

1.8.1 parse方法用來把字符串轉換成對象

querystring.parse(str,[sep],[eq],[options]);
複製代碼

1.8.2 stringify方法用來把對象轉換成字符串

querystring.stringify(obj,[sep],[eq]);
複製代碼

1.9 querystring

url.parse(urlStr,[parseQueryString]);
複製代碼
  • href 被轉換的原URL字符串
  • protocal 客戶端發出請求時使用的協議
  • slashes 在協議與路徑之間是否使用了//分隔符
  • host URL字符串中的完整地址和端口號
  • auth URL字符串中的認證部分
  • hostname URL字符串中的完整地址
  • port URL字符串中的端口號
  • pathname URL字符串的路徑,不包含查詢字符串
  • search 查詢字符串,包含?
  • path 路徑,包含查詢字符串
  • query 查詢字符串,不包含起始字符串?
  • hash 散列字符串,包含#

1.10 發送服務器響應流

http.ServerResponse對象表示響應對象服務器

1.10.1 writeHead

response.writeHead(statusCode,[reasonPhrase],[headers]);
複製代碼
  • content-type 內容類型
  • location 將客戶端重定向到另一個URL地址
  • content-disposition 指定一個被下載的文件名
  • content-length 服務器響應內容的字節數
  • set-cookie 在客戶端建立Cookie
  • content-encoding 指定服務器響應內容的編碼方式
  • cache-cache 開啓緩存機制
  • expires 用於制定緩存過時時間
  • etag 指定當服務器響應內容沒有變化不從新下載數據

1.10.2 Header

設置、獲取和刪除Headercookie

response.setHeader('Content-Type','text/html;charset=utf-8');
response.getHeader('Content-Type');
response.removeHeader('Content-Type');
response.headersSent 判斷響應頭是否已經發送
複製代碼

1.10.3 headersSent

判斷響應頭是否已經發送socket

let http = require('http');
let server = http.createServer(function(req,res){
  console.log(resopnse.headersSent?"響應頭已經發送":"響應頭未發送!");
  res.writeHead(200,'ok); console.log(resopnse.headersSent?"響應頭已經發送":"響應頭未發送!"); }); 複製代碼

1.10.4 sendDate

不發送Date網站

res.sendDate = false;
複製代碼

1.10.5 write

能夠使用write方法發送響應內容ui

response.write(chunk,[encoding]);
response.end([chunk],[encoding]);
複製代碼

1.10.6 timeout

能夠使用setTimeout方法設置響應讓超時時間,若是在指定時間內不響應,則觸發timeout事件編碼

response.setTimeout(msecs,[callback]);
response.on('timeout',callback);
複製代碼

1.10.7 close

在響應對象的end方法被調用以前,若是鏈接中斷,將觸發http.ServerResponse對象的close事件url

response.on('close',callback);
複製代碼

1.10.8 parser

net
onconnection

_http_server.js
鏈接監聽
connectionListenerInternal
socketOnData
onParserExecuteCommon
parserOnIncoming


複製代碼

2. HTTP客戶端

2.1 向其餘網站請求數據

let req = http.request(options,callback);
req.on('request',callback);
request.write(chunk,[encoding]);
request.end([chunk],[encoding]);

複製代碼
  • host 指定目標域名或主機名
  • hostname 指定目標域名或主機名,若是和host都指定了,優先使用hostname
  • port 指定目標服務器的端口號
  • localAddress 本地接口
  • socketPath 指定Unix域端口
  • method 指定HTTP請求的方式
  • path 指定請求路徑和查詢字符串
  • headers 指定客戶端請求頭對象
  • auth 指定認證部分
  • agent 用於指定HTTP代理,在Node.js中,使用http.Agent類表明一個HTTP代理,默認使用keep-alive鏈接,同時使用http.Agent對象來實現全部的HTTP客戶端請求
let http = require('http');
let options = {
    hostname: 'localhost',
    port: 8080,
    path: '/',
    method: 'GET'
}
let req = http.request(options, function (res) {
    console.log('狀態嗎:' + res.statusCode);
    console.log('響應頭:' + JSON.stringify(res.headers));
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
        console.log('響應內容', chunk);
    });
});
req.end();
複製代碼

2.2 取消請求

能夠使用abort方法來終止本次請求

req.abort();
複製代碼

2.3 監聽error事件

若是請求過程當中出錯了,會觸發error事件

request.on('error',function(err){});
複製代碼

2.4 socket

創建鏈接過程當中,爲該鏈接分配端口時,觸發socket事件

req.on('socket',function(socket){
  socket.setTimeout(1000);
  socket.on('timeout',function(){req.abort()});
});
複製代碼

2.5 get

能夠使用get方法向服務器發送數據

http.get(options,callback);
複製代碼

2.6 addTrailers

能夠使用response對象的addTrailers方法在服務器響應尾部追加一個頭信息

let http = require('http');
let path = require('path');
let crypto = require('crypto');


let server = http.createServer(function (req, res) {
    res.writeHead(200, {
        'Transfer-Encoding': 'chunked',
        'Trailer': 'Content-MD5'
    });
    let rs = require('fs').createReadStream(path.join(__dirname, 'msg.txt'), {
        highWaterMark: 2
    });
    let md5 = crypto.createHash('md5');
    rs.on('data', function (data) {
        console.log(data);
        res.write(data);
        md5.update(data);
    });
    rs.on('end', function () {
        res.addTrailers({
            'Content-MD5': md5.digest('hex')
        });
        res.end();
    });
}).listen(8080);
複製代碼
let http = require('http');
let options = {
    hostname: 'localhost',
    port: 8080,
    path: '/',
    method: 'GET'
}
let req = http.request(options, function (res) {
    console.log('狀態嗎:' + res.statusCode);
    console.log('響應頭:' + JSON.stringify(res.headers));
    res.setEncoding('utf8');
    res.on('data', function (chunk) {
        console.log('響應內容', chunk);
    });
    res.on('end', function () {
        console.log('trailer', res.trailers);
    });
});
req.end();
複製代碼

2.7 製做代理服務器

let http = require('http');
let url = require('url');
let server = http.createServer(function (request, response) {
    let {
        path
    } = url.parse(request.url);
    let options = {
        host: 'localhost',
        port: 9090,
        path: path,
        headers: request.headers
    }
    let req = http.get(options, function (res) {
        console.log(res);
        response.writeHead(res.statusCode, res.headers);
        res.pipe(response);
    });
    req.on('error', function (err) {
        console.log(err);
    });
    request.pipe(req);
}).listen(8080);複製代碼
相關文章
相關標籤/搜索