深入學習HTTP(一)
阿新 • • 發佈:2019-01-22
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 }