>> buffer
Buffer對象是全局對象
Buffer支持的編碼方式:ascii, utf8, base64, binary
new Buffer(size)
new Buffer(array)
new Buffer(str, encoding='utf8')html
buffer.write(str,offset=0, encoding='utf8')
buffer.toString(encoding, start=0, end=buffer.length);node
buffer[index]web
Buffer.byteLength(string, encoding='utf8')
buffer.length //分配給buffer對象的內存大小 字節爲單位shell
buffer.copy(targetBuffer, targetStart, sourceStart, sourceEnd=buffer.length)
buffer.slice(start, end);//返回引用同一段內存的buffer對象, 注意和str.slice()不一樣api
>> eventEmitter
全部可以觸發事件的對象都是 events.eventEmitter 的實例。
註冊新的事件監聽器時,會觸發 newListener 事件
出錯則觸發 error事件,若沒被捕獲,則輸出調用棧,並退出應用數組
* event: newListener
* event: error瀏覽器
* emitter.on(event, listener); //向監聽器數組添加1個監聽器
如:
server.on('stream', function(){
console.log('someone connected');
});緩存
* emitter.removeListener(event, listener); //從指定監聽器數組,移除指定監聽器 (監聽器數組從新調整索引 splice)
如:
var callback = function(stream){ console.log('someone connected!')};安全
server.on('stream', callback);
//...
server.removeListener('stream', callback);服務器
* emitter.removeAllListeners(event)
* emitter.listeners(event); //返回指定事件的監聽器數組
* emitter.emit(event, [arg1], [arg2],...); //觸發事件
>> streams
stream是一個抽象接口,node中不少對象都實現了這個接口(如 request, stdout), stream對象是EventEmitter的實例。
stream能夠是 只讀,只寫,可讀可寫 的
> readable stream 只讀流
只讀流的方法、屬性和事件
* event:data
stream.on(data, function(data){
//data: buffer or string (若調用過setEncoding())
});
* event:end
流遇到EOF或TCP中的FIN時觸發,表示不會再有數據進來
stream.on('end', function(){ });
* event:error
stream.on('error', function(exception){ });
* event:close
內部的文件描述符被關閉時觸發
stream.on('close',function(){ });
* event:fd
當數據流接收到文件描述符信息時觸發 (一個文件的數據流信息包括2部分:文件描述符信息和文件的數據信息) unix流
stream.on('fd', function(fd){ });
* stream.readable
* stream.setEncoding(encoding);
設置data事件返回的是字符串而不是buffer對象,編碼方式有:ascii, utf8, base64
* stream.pause(); //暫停觸發data事件
* stream.destroy();
關閉內部的文件描述符,這樣流不會再觸發任何事件
> writable stream 可寫流
可寫流的方法、屬性和事件:
* event:drain
在一個write方法被調用並返回false後觸發,表示可安全地再次寫入該stream
stream.on('drain', function(){ });
* event:error
stream.on('error', function(exception){ });
* event:close
當底層的文件描述符已終止時觸發
stream.on('close', function(){ });
* stream.writable
* stream.write(string, encoding='utf8',[fd]);
用指定的編碼方式編碼字符串後寫入流中,若字符串被成功刷新到內核緩衝區則返回true, 不然返回false, 數據在將來寫入。
drain事件通知內核緩衝區什麼時候爲空
* stream.write(buffer); 同上
* stream.end();
經過EOF或FIN來終止流
* stream.end(string, encoding); //~~至關於 stream.write(string, encoding) 後,stream.end()
* stream.end(buffer); //同上
* stream.destroy();
終止底層的文件描述符,以後流不會發出任何事件
>> global objects 全局對象
* global
全局命名空間對象 ~~相似於瀏覽器環境下的window?
* process 進程對象
* require() 加載依賴模塊
* require.paths
一個保存了require函數搜索路徑的數組,可往裏面添加自定義路徑
* __filename
當前正在執行的腳本的絕對路徑
* __dirname
當前正在執行腳本的文件夾
* module
指向當前模塊的引用, module.exports 和 exports指向同一個引用
> process 進程
process對象是EventEmitter的實例
* event:exit
進程退出時觸發,是檢查模塊狀態的好地方(如單元測試)
process.on('exiti', function(){ });
如:
process.on('exit', function(){
process.nextTick(function(){//下一次事件循環
console.log('this will not run');
});
console.log('about to exit');
});
* event:uncaughtException 未捕獲異常
process.on('uncaughtException', function(error){ });
如:
process.on('uncaughtException',function(error){
console.log('caught exception:' + error);
});
setTimeout(function(){
console.log('this will still run');
});
nosuchFn();
console.log('this will not run');
* signal events
當進程接收到信號時被觸發, POSIX信號列表(SIGINT, SIGUSR1)
監聽SIGINT信號示例:
var stdin = process.openStdin();
process.on('SIGINT', function(){
console.log('Got SIGINT, press ctrl+D to exit')
});
發送SIGINT信號最簡單的方法 ctrl+C
* process.stdout
一個表明標準輸出的流對象
console.log的定義:
console.log = function(m){
process.stdout.write(d + '\n');
};
* process.openStdin()
打開標準輸入流,返回一個只讀流對象
如:打開標準輸入流,同時監聽2個事件
var stdin = process.openStdin();
stdin.setEncoding('utf8');
stdin.on('data', function(chunk){
process.stdout.write('data:'+chunk);
});
stdin.on('end', function(){
process.stdout.write('end');
});
* process.argv
保存命令行參數的數組,argv[0]是node的路徑,argv[1]是如今執行js的路徑,argv[2],...纔是命令行輸入的參數
* process.execPath
進程可執行文件的絕對路徑
> console.log(process.execPath)
D:\Program Files\nodejs\node.exe
* process.chdir(directory)
改變進程的當前目錄,失敗時拋出異常
* process.compile(code, filename); //process.compile->undefined??
同eval方法,能夠指定文件名,更友好地輸出錯誤信息 ~~~把code看作是filename文件裏的代碼來執行
code參數的代碼沒法訪問本地做用域
eval(code); //code能夠訪問本地做用域
如:
var localVar = 123, compiled, evaled;
compiled = process.compile('localVar=1', 'myfile.js');
console.log('localVar:' + localVar + ', compiled:' + compiled);
evaled = eval('localVar = 1');
console.log('localVar:' + localVar +', evaled:' + evaled);
* process.cwd()
返回進程的當前工做目錄
* process.env
一個保存用戶環境變量的對象
* process.exit(code=0)
退出進程,返回退出狀態碼
process.exit(0); //正常退出
process.exit(1); //執行node的shell將會獲得返回值1. 非0 則表示異常退出
* process.getgid(); //process.getgid -->undefined ??
返回進程的用戶組id, 數字
* process.setgid(id) //undefined??
設置當前進程的用戶組id, id參數能夠爲數字id或組名字符串
* process.getuid() //當前進程的用戶id
* process.setuid(id) //設置當前進程的用戶id
* process.version //編譯進可執行文件的屬性, 表明NODE_VERSION
* process.installPrefix //編譯進可執行文件的屬性, 表明NODE_PREFIX undefined ??
* process.kill(pid, signal='SIGINT')
向一個進程發送信號,pid爲進程id, signal描述要發送信號的字符串,默認爲SIGINT
如:
process.on('SIGHUP', function(){
console.log('Got SIGHUP signal');
});
setTimeout(function(){
console.log('exiting');
process.exit(0);
},100);
process.kill(process.pid, 'SIGHUP');
* process.pid //當前進程id
* process.title //獲取或設置命令行窗口的標題
* process.platform //平臺
> process.platform
'win32'
* process.memoryUsage();
返回一個描述node進程內存佔用狀況的對象
* process.nextTick(callback)
在事件循環的下一輪調用這個回調。此函數不是 setTimeout(callback,0)的別名,它更高效
* process.umask([mask])
設置或讀取進程的文件建立模式掩碼
>> sys
* sys.print(string) //同console.log(),只是沒有結尾的換行符
* sys.debug(string)
同步輸出函數,阻塞進程並將字符串打印到標準錯誤輸出中(stderr) ~~~阻塞版的console.error
* sys.log(string)
將字符串輸出到標準輸出(stdout 即控制中),並附加時間戳
* sys.inspect(object, showHidden=false, depth=2)
序列化 調試中頗有用
showHidden爲true,則非枚舉屬性也會被轉化
depth爲遞歸深度,null則無限遞歸
* sys.pump(readableStream, writableStream, callback); //實驗性的api
數據流從只讀流到可寫流
>> timers
* setTimeout(callback, delay, [arg],[...]);
* clearTimeout(timeoutId);
* setInterval(callback, delay,[arg],[...]);
* clearInterval(intervalId)
>> child_process子進程
程序能夠經過子進程的stdin, stdout,stderr以徹底非阻塞的方式傳遞數據
建立子進程 require('child_process').spawn()
每一個子進程總帶有3個流對象 child.stdin, child.stdout, child.stderr
子進程的事件、方法和屬性
* event:exit
child.on('exit', function(code, signal){ });
子進程結束後被觸發,若正常結束 參數code爲子進程的退出碼,不然爲null; 若子進程由於信號而終止,signal參數爲信號名稱,不然爲null
* child.stdin
* child.stdout
* child.stderr
* child.pid
* child.spawn(cmd, args=[], [options])
使用指定的命令行參數建立新進程
options默認值以下
{
cwd:undefined, //指定新進程的工做目錄
env:process.env, //指定新進程可見的環境變量
customFds:[-1,-1,-1] //[stdin, stdout, stderr]綁定到指定的流, -1表示建立新的流
}
* child.exec(command, [options], callback)
使用子進程執行命令,並將子進程的輸出以回調函數參數的形式返回
* child.kill(sigal='SIGTERM')
向子進程發送信號 不指定則默認信號爲SIGTERM
>> Script
Script類能夠編譯執行js代碼
訪問Script類: var Script = process.binding('evals').Script;
* Script.runInThisContext(code,[filename]);
編譯code參數包含的代碼,並返回結果,如同這些代碼是從filename文件中加載的同樣,同process.compile()
執行的代碼並不訪問本地做用域
var localVar = 123, usingScript, evaled,
Script = process.binding('evals').NodeScript;
console.log(typeof Script);
console.log(Script.runInThisContext);
usingScript = Script.runInThisContext('localVar = 1;', 'myfile.js');
console.log('localVar:' + localVar +' ,usingScript:' + usingScript);
evaled = eval('localVar = 1;');
console.log('localVar:' + localVar + ' , evaled:' + evaled);
* Script.runInNewContext(code, [sandbox],[filename]);
編譯代碼並在sandbox參數指定的做用域中執行和返回結果,其餘同Script.runInThisContext()
Script.runInNewContext()方法很是有用,它能夠在一個獨立的線程中執行不信任的代碼,防止全局變量被意外修改。
* new Script(code, [filename]);
返回包含編譯好code參數代碼的Script對象,這個script對象能夠用下面的方法來執行內部編譯好的代碼,
這個script對象能夠在運行時綁定到指定的對象,每次綁定只在運行時有效
* script.runInThisContext() //與Script.runInThisContext()相似(1個是對象的方法,一個是類的方法)
script.runInThisContext()執行的是script對象內包含的代碼並返回結果,執行的代碼不能訪問本地做用域,可是能夠訪問全局做用域
script.runInThisContext實現一次編譯,屢次執行:
var Script = process.binding('evals').NodeScript;
var scriptObj, i;
globalVar = 0;
scriptObj = new Script('globalVar += 1;', 'myfile.js');
for(i=0; i<1000; i++){
scriptObj.runInThisContext();
}
console.log('globalVar:' + globalVar);
* script.runInNewContext([sandbox]) //與Script.runInNewContext(sandbox)函數相似
將sandbox指定的對象做爲全局對象來執行代碼,並返回結果。不訪問本地做用域
var sys = require('sys');
var Script = process.binding('evals').NodeScript;
var scriptObj, i;
var sandbox = {
animal:'cat',
count:2
};
scriptObj = new Script('count += 1; name="kitty";', 'myfile.js');
for(i=0; i<10; i++){
scriptObj.runInNewContext(sandbox);
}
console.log(sys.inspect(sandbox));
>> filesystem 文件系統
文件的I/O是由標準的POSIX函數封裝而成的。fs的api都設有同步和異步方式。
//async unlink
var fs = require('fs');
fs.unlink('./note/hello.js', function(err){
if(err) throw err;
console.log('successfully delete the file');
});
console.log('last statement');
//sync unlink
var fs = require('fs');
fs.unlinkSync('./note/hello.js');
console.log('successfully delete the file');
//多個回調函數的執行順序是不肯定的,要有序的話,須要嵌套回調
// fs.rename() -> fs.stat
var fs = require('fs');
fs.rename('./note/hi.js', './note/hello.js', function(err){
if(err) throw err;
fs.stat('./note/hello.js', function(err, stats){
if(err) throw err;
console.log( JSON.stringify(stats) );
});
});
* fs.unlink(file, callback), fs.rename(oldfile, newfile, callback)
* fs.unlinkSync(file), fs.renameSync(oldfile, newfile)
* fs.truncate(fd, len, [callback]) //截取
* fs.truncateSync(fs, len)
* fs.chmod(path, mode, [callback])//異步更改文件權限
* fs.chmodSync(path, mode);
* fs.stat(path, [callback]); //異步讀取文件屬性
fs.stat(path, function(err, stats){ })
* fs.lstat(path, [callback]) //利用路徑異步讀取連接的屬性 path參數爲一個符號連接
fs.lstat(path, function(err, lstats){ })
* fs.fstat(fd, [callback]); //利用文件描述符異步讀取屬性
* fs.link(srcpath, dstpath, function(err){ }); //異步創建鏈接
* fs.symlink(linkdata, path, function(err){ }); //異步創建符號鏈接
* fs.readlink(path, function(err, resolvedPath){ }) //異步讀取鏈接
* fs.realpath(path, function(err, resolvedPath){ }) //異步讀取絕對路徑
* fs.unlink(path, fucntion(err){ }) // ~=delete
* fs.rmdir(path, function(err){ }) //
* fs.mkdir(path, mode, function(err){ }) //異步刪除目錄
* fs.readdir(path, function(err, arr){ }); //異步讀取目錄中的內容
* fs.close(fd, function(err){ });
* fs.open(path, flags, mode=066, callback);
異步打開文件 flag能夠爲:r , r+, w, w+, a
* fs.write(fd,buffer, offset, length, postion, callback)
經過文件描述符fd, 寫入緩衝區到文件
offset,length 決定哪部分緩衝區被寫入
position決定寫入位置
* fs.writeSync(fd, buffer, offset, length, position);
fs.write(緩衝區)的同步方式,返回寫入動做的數據大小
* fs.writeSync(fd, string, position, encode='utf8');
fs.write(字符串)的同步方式,返回寫入動做的數據大小
* fs.read(fd, length, position, encoding, callback)
* fs.readFile(filename, [encoding] , [callback])
經過文件路徑異步讀取文件
fs.readFile('note/hello.js', function(err, data){
if(err) throw err;
console.log(data);
})
* fs.writeFile(filename, data, encoding='utf8', callback)
* fs.watchFile(filename, [options], listener)
監聽文件的變化
options:{
persistent: true | false, //是否持續檢查
interval: 200 //檢測間隔 單位毫秒
}
fs.watchFile('myfile.js', function(curr, prev){
console.log(curr.mtime, prev.mtime);
});
* fs.unwatchFile(filename);
中止監聽文件的變化
* fs.Stat 獲取文件的信息
fa.stat() 和 fs.lstat()函數返回 stats對象:
stats.isFile()
stats.isDirectory()
stats.isBlockDevice()
stats.isCharacterDevice()
stats.isSymbolicLink() ( only true width fs.lstat() )
stats.isFIFO()
stats.isSocket()
> fs.ReadStream 讀取文件
* fs.createReadStream(path, [options]);
新建一個只讀流對象
options是一個默認值以下的對象:
{
flag:'r',
encoding:null,
mode:0666,
bufferSize:4*1024
}
options對象能夠包含 屬性start和end從文件中讀取一個範圍的數據,而不是整個文件,start和end必須同時指定。
fs.createStream('sample.txt',{start:90, end:99});
> fs.WriteStream 寫入文件
* ws = fs.createWriteStream(path, [options]);
options默認值:
{
flags:'w',
encoding:null,
mode:0666
}
* event:open
ws.on('open', function(fd){ });
>> HTTP
> http.Server 模塊
* event:request
server.on('request',function(request, response){ })
request是http.ServerRequest的一個實例,response是http.ServerResponse的一個實例
每一個請求發生時觸發,每一個鏈接可能會有多個請求(在 keep-alive的狀況下 )
* event:connection
server.on('connection', function(stream){ })
當一個新的TCP stream創建後發出此消息。 stream是net.Stream的對象
* event:close
server.on('close', function(errno){ })
當服務器關閉時觸發
* event:upgrade
server.on('upgrade', function(request, socket, head){ })
每當客戶端請求一個http upgrade時觸發,若upgrade事件沒被監聽,則請求upgrade的客戶端的鏈接將被關閉
參數:
request: 一個http請求,http.ServerRequest的實例
socket:服務器和客戶端之間鏈接用的網絡 socket
head: Buffer的實例
* event:clientError
server.on('clientError',function(exception){ })
客戶端鏈接出錯時觸發
* http.createServer(requestListener)
返回一個新的web server對象
requestListener是一個request事件的監聽器
* server.listen(port, [hostname], [callback])
在指定的端口和主機上接受鏈接。若hostname沒寫,則在此機器的全部ipV4地址上接受鏈接(INADDR_ANY)
若要在UNIX SOCKET上監聽的話,則須要提供一個文件名來替代端口號和主機名
server.listen()是一個異步方法,server在指定端口綁定好後,執行回調callback
* server.listen(path, callback)
建議一個UNIX SOCKET服務器,並在指定路徑上監聽
* server.setSecure(credentials)
容許此server支持HTTPS
* server.close()
再也不接受任何新鏈接
* server.maxConnections
最大鏈接數
* server.connections
當前鏈接數
> http.ServerRequest
http.ServerRquest對象一般由http.Server創建而非用戶手動創建,而且會做爲request事件監聽器的第一個參數傳遞進去
http.ServerRequest對象的事件、方法和屬性:
* event: data
request.on('data', function(chunk){ })
當接收到信息體中的一部分時觸發
request.setBodyEncoding()方法可設置消息體的編碼 (注:傳輸編碼不一樣於字符編碼)
* event:end
request.on('end', function(){ })
每次徹底接收消息後觸發,該事件後不會觸發其餘事件
* request.method
一個只讀字符串 如:GET, DELETE
* request.url
表明所請求的url ,~~ 非完整url? 如:'/status?name=ryan'
解析url各個部分:依賴url模塊
require('url').parse(request.url);
require('url').parse(request.url, true);
require('querystring').parse(request.url)
* request.headers
請求頭部信息 只讀
* request.httpVersion
http協議的版本 如 1.1, 1.0 request.httpVersionMajor, request.httpVersionMinor
* request.setEncoding(encoding=null)
設置請求體的字符編碼 utf8, binary, null. 默認爲null, 這個設置影響到 request的data事件回調函數接收到的data是一個buffer對象仍是字符串。
* request.pause()
暫停請求,對於控制上傳很是有用
* request.resume()
恢復一個暫停的request
* request.connection
一個表明當前鏈接的net.Stream對象
> http.ServerResponse
這個對象通常有 http.Server創建而非用戶手動創建,做爲request事件監聽器的第二個參數,是一個可寫流
* response.writeHead(statusCode, [reasonPhrase], [headers])
用來發送一個響應報文頭給本次的請求方
如:
var body = 'hello world';
response.writeHead(200, {
'content-length':body.length,
'content-type': 'text/plain'
})
* response.write(chunk, encoding='utf8');
負責發送響應報文的部分數據,必須在response.writeHead()方法以後調用
參數:
chunk:能夠是字符串或buffer對象,若爲字符串則用encoding參數指定的編碼方式將其編碼爲字節流
response對象只緩存消息體的第一個數據塊,其餘的數據以流的方式發送,沒被緩存
* response.end(data, encoding='utf8');
通知服務器全部響應的報文頭和報文體已全發出
> http.Client
使用服務器地址做爲參數來構造一個http.Client, 其返回的句柄能夠用來發送一個或多個請求
//鏈接到baidu
var http = require('http');
var baidu = http.createClient(80, 'www.baidu.com');
var request = baidu.request('GET' ,'/', {host:'www.baidu.com'});
request.end();
request.on('response', function(response){
console.log('STATUS:' + response.statusCode);
console.log('HEADERS:' + JSON.stringify(response.headers));
response.setEncoding('utf8');
response.on('data', function(chunk){
console.log('BODY:' + chunk);
});
});
* event: upgrade
client.on('upgrade', function(request, socket, head){ })
當服務器響應upgrade請求時觸發
* http.createClient(port, host='localhost', secure=false, [credentials])
構建一個http客戶端 port和host指明要鏈接的目標
* client.request(method='GET' , path, [request_headers])
發出一個http請求,必要時創建一個流,該函數返回http.ClientRequest對象
若想發送一個信息體,記得要在頭部信息中包含content-length,以流的方式發送請求體,則設置transfer-Encoding:chunked
* client.verifyPeer();
返回 true/false 並在上下文附帶服務器定義的或者缺省數字認證中心的有效證書列表。
* client.getPeerCertificate()
返回用 JSON 結構詳盡表述的服務器方證書
> http.ClientRequest
http.Client的request()方法創建並返回http.ClientRequest對象。該對象表明一個進行中的請求,請求頭已經發出去了。
* event:response
request.on('response', function(response){ //response 爲 http.ClientResponse的實例
response.on('data', function(chunk){
console.log('BODY:' + chunk);
});
});
* request.write(chunk, encoding='utf8');
發送請求體的部分數據,屢次調用write方法,從而讓請求體以流的方式發送到服務器。
* request.end([data], [encoding]);
完成本次請求的發送
> http.ClientResponse
這個對象在http.Client發起請求時被建立,它會做爲request對象的response事件回調函數的參數 ,爲只讀流
http.ClientResponse的事件、方法和屬性:
* event:data
response.on('data', function(chunk){ });
當接收到消息體一部分時觸發, response.setBodyEncoding()方法設置消息體的編碼
* event:end
response.on('end', function(){ })
接收完
* response.statusCode
http狀態碼
* response.httpVersion
所鏈接到服務器的http協議版本
* response.headers
響應頭
* response.setBodyEncoding(encoding=null)
設置響應體編碼
* response.pause()
暫停response觸發事件,一般用於控制下載動做
* response.resume()
恢復暫停的response
* response.client
保存response所屬的http.Client的引用
>> net.Server.TCP服務器模塊
net.Server用來創建TCP或UNIX服務器的
如:
var net = require('net');
var server = net.createServer(function(stream){
stream.setEncoding('utf8');
stream.on('connection', function(){
stream.write('hello\r\n');
});
stream.on('data',function(data){
stream.write(data);
});
stream.on('end', function(){
stream.write('goodbye \r\n');
stream.end();
});
}).listen(8124, 'localhost');
net.Server對象的事件、方法和屬性:
* event:connection
server.on('connection', function(stream){ })
創建新鏈接時觸發,stream是net.Stream的實例
* event:close
server.on('close', function(){ })
* net.createServer(connectionListener)
創建一個TCP Server
* server.listen(port, [host], [callback]);
監聽指定端口,綁定好後執行回調
* server.listen(path, callback);
創建一個UNIX SOCKET服務器,並在指定路徑上監聽
* server.listenFD(fd)
監聽指定的文件描述符
* servre.close()
中止服務器,是異步方法,服務器觸發close事件後才最終關閉
> net.Stream TCP流模塊
這個對象是對TCP或UNIX SOCKET的抽象,它實現了全雙工的流接口。
net.Stream能夠由用戶手動創建,並做爲一個客戶端來使用
net.Stream的事件、方法和屬性:
* event:connect
stream.on('connect',function(){ })
成功創建鏈接後觸發
* event:secure
stream.on('secure', function(){ })
創建一個安全的SSL握手後觸發
* event:data
stream.on('data', function(data){ })
接收到數據時觸發
* event:end
stream.on('end',function(){ })
當stream發出一個FIN包後觸發
* event:timeout
stream.on('timeout',function(){ })
當流由於不活動而超時時觸發,惟一一個由於stream空閒而通知的事件,這時用戶必須手動關閉鏈接
* event:drain
stream.on('drain',function(){ })
當寫緩衝區變空時觸發,可用來控制上傳
* event: error
stream.on('error',function(exception){ })
錯誤時觸發
* event: close
stream.on('close',function(had_error){ })
當stream被徹底關閉時觸發
* net.createConnection(port, host=127.0.0.1)
打開一個綁定到指定端口和主機的stream對象 host參數默認爲localhost
* stream.connect(port, host=127.0.0.1)
在指定的端口和主機上打開一個stream, 創建鏈接後發觸發 connect事件
* stream.remoteAddress
遠程計算機的ip
* stream.readyState
流的狀態:closed, opening, open, readOnly, writeOnly
* stream.setEncoding(encoding=null)
爲接收到的數據設置編碼格式 ascii, utf8, base64
* stream.setSecure([credentials])
支持HTTPS
* stream.verifyPeer()
* stream.getPeerCertificate()
* stream.write(data, encoding='ascii');
* stream.end([data], [encoding]);
* stream.pause()
* stream.resume()
* stream.setTimeout()
* stream.setNoDelay(noDelay=true)
* stream.setKeepAlive(enable=false, [initailDelay])
>> crypto 加密模塊
>> DNS 域名解析
dns = require('dns')
dns.resolve4(domain,callback)
dns.reverse(address, callback)
* dns.lookup(domain, family=null, function(err, address, family){ })
將一個域名(www.baidu.com)解析爲找到的第一個A(IPV4)或AAAA(IPV6)記錄
* dns.resolve(domain, rrtype='A', function(err, address){ });
將域名按照指定的類型解析到一個數組裏面
參數:
rrtype:解析的類型,包括 A(ipv4地址), AAAA(ipv6地址), MX(mail exchange record), TXT(text records), SRV(SRV records), PTR(using for revers IP lookups);
dns.resolve()的快捷方法以下:
* dns.resolve4(domain, function(err, addresses){ })
相似dns.resolve()方法,只是僅對ipv4地址進行查詢(即 A records), addresses是一個ip地址的數組
* dns.resolve6(domain, function(err, addresses){ });
對ipv6地址進行查詢
* dns.resolveMx(domain, callback);
* dns.resolveTxt(domain, callback)
* dns.resolveSrv(domain, callback)
* dsn.reverse(ip, function(err, domains))
反向解析一個ip地址到一個域名數組
>> dgram 數據報
dgram = require('dgram'),數據報通常用來處理IP/UDP信息
dgram的事件、方法和屬性:
* event:message
dgram.on('message', function(msg, rinfo){ })
當一個SOCKET接收到新的數據包時觸發,msg:緩衝區變量, rinfo:包含發送者地址和數據包字節長度的對象
* event:listening
dgram.on('listening', function(){ })
當一個SOCKET開始監聽數據包的時觸發
* event:close
dgram.on('close',function(){ })
當一個SOCKET使用close()方法關閉時觸發
* dgram.createSocket(type, [callback]);
創建一個指定類型的數據包SOCKET, type能夠是: udp4, udp6, unix_dgram
* dgram.send(buf, offset, length, path, [callback]);
* dgram.send(buf, offset, length, port, address,[callback])
* dgram.bind(path)
僅在UNIX DOMAIN DATAGRAM SOCKET中使用
* dgram.bind(port, [address]);
對於UDP SOCKET,在指定的端口和可選的地址上監聽
* dgram.close()
關閉非延遲的SOCKET而且中止監聽數據
* dgram.address()
返回包含SOCKET地址信息的一個對象
* dgram.setBroadcast(flag)
設置或清除SO_BROADCASET選項
* dgram.setTTL(ttl)
設置IP_TTL這個選項,ttl用來設置HOPS的數值從1到255,大多數系統默認設置爲64
>> Assert 斷言
assert = require('assert') 此模塊用來編寫單元測試
* assert.fail(actual, expected, message, operator)
用operator測試actual和expected是否相等
* assert.ok(value, [message]);
測試value是否爲true 等價於 assert.equal(true, value, message)
* assert.equal(actual, expected, [message])
用操做符== 比較actual和expected是否相等
* assert.notEqual(actual, expected,[message])
用操做符!= 比較actual和expected
* assert.deepEqual(actual, expected, [message])
深度比較是否相等
a = {a:1, b:2};
b = {b:2, a:1};
assert.equal(a,b) //false
assert.deepEqual(a,b) //true
assert.strictEqual(a,b) //false
* assert.notDeepEqual(actual, expected, [message])
深度比較是否不相等
* assert.strictEqual(actual, expected, [message]), assert.notStrictEqual(..)
用=== 和 !== 比較是否嚴格相等/不等
* assert.throw(block, [error], [message]), assert.notThrow(...)
測試代碼 期待其拋出(/不拋出)異常
* assert.ifError(value)
value不爲false,則拋出異常。 實現代碼:assert.ifError = function(err){ if(err) throw(err)}
>> Path 模塊
此模塊包含不少用來處理文件路徑的小工具,
path = require('path');
* path.join([path1],[path2],...);
將全部參數連起來解析成新的路徑
* path.normalizeArray(arr) //? path.normalizeArray : undefined
轉化路徑的各部分,將'..' 和 '.'替換爲實際的路徑
* path.normalize(path)
轉化路徑字符串,將'..' 和 '.'替換爲實際的路徑
* path.dirname(path)
返回表明文件夾的部分
* path.basename(path, [ext]);
返回路徑的最後一部分
* path.extname(path)
返回路徑中文件的擴展名
* path.exists(path, [callback]) ~~fs.exists()
判斷路徑是否存在,傳遞true/false給callback
>> URL 模塊
url = require('url')
url: http://user:pass@host.com:8080/p/a/t/h?query=string#hash
解析後的url對象
{
href:'http://user:pass@host.com:8080/p/a/t/h?query=string#hash'
,protocol:'http'
,host:'user:pass@host.com:8080'
,auth:'user:pass'
,hostname:'host.com'
,port:8080
,pathname:'/p/a/t/h'
,search:'?query=string'
,query:'query=string' //或 {query:'string'}
,hash:'#hash'
}
* url.parse(urlStr, parseQueryString=false)
解析url字符串返回一個對象
* url.format(urlObj)
url對象格式化爲url字符串
* url.resolve(from, to)
接收一個base Url 和 href url,像解析錨點同樣解析
> url.resolve('www.baidu.com','#gogo')
'www.baidu.com#gogo'
>> QueryString 查詢字符串
querystring = require('querystring');
* querystring.stringify({foo:'bar'}); //foo=bar
querystring.stringify({foo:'bar', baz:'boo'}, ';', ':'); //foo:bar;baz:boo
* querystring.parse(str, sep="&", eq="=");
反序列化查詢字符串
* querystring.escape
querystring.stringify中使用的escape方法,能夠覆寫它
* querystring.unescape
querystring.parse中使用的unescape方法,能夠覆寫它
>> REPL交互執行 (Read Execute Print Loop)
node的REPL模式能夠單獨執行,也能夠嵌入到其餘程序中。
直接執行node,不帶任何參數,會進入REPL模式
設置環境變量NODE_NO_READLINE=1,則能夠啓用高級行編輯功能
_ 保存上一個表達式的值
REPL提供訪問全局做用域內變量的能力
repl = require('repl');
repl.start('node>').context.m = 'my message';
REPL的一些命令:~~~ repl環境下 .help查看全部命令
.break, .clear, .exit, .help, .load, .save
>> Modules 模塊
node使用 commonJs的模塊系統
----------------------------------
ruanyifeng
----------------------------------
>> fs模塊:
fs.readFile(path,function(err, file){..})
fs.readFile(path,coding, function(err, file){ ...})
fs.writeFile(path, data,function(err){...})
fs.readdir(path, function(err, files){..})
fs.rmdir(path);
fs.exists(path, function(exist){..});//指定文件或目錄是否存在
fs.open(path, callback); //open方法會檢測文件是否存在
>> stream模塊
Stream是數據處理的一種形式,能夠用來取代回調函數。舉例來講,傳統形式的文件處理,必須先將文件所有讀入內存,而後調用回調函數,若是遇到大文件,整個過程將很是耗時。Stream則是將文件分紅小塊讀入內存,每讀入一次,都會觸發相應的事件。只要監聽這些事件,就能掌握進展,作出相應處理,這樣就提升了性能。Node內部的不少IO處理都採用Stream,好比HTTP鏈接、文件讀寫、標準輸入輸出。
Stream是一個抽象接口,定義了readable、writable、drain、data、end、open、lose等事件。它既能夠讀取數據,也能夠寫入數據。讀寫數據時,每讀入(或寫入)一段數據,就會觸發一次data事件,所有讀取(或寫入)完畢,觸發end事件。若是發生錯誤,則觸發error事件。
fs模塊的createReadStream方法用於新建讀取數據流,createWriteStream方法用於新建寫入數據流。使用這兩個方法,能夠作出一個用於文件複製的腳本copy.js。
var readStream = fs.createReadStream(path)
var writeStream = fs.createWriteStream(path);
Streams對象都具備pipe方法,起到管道做用,將一個數據流輸入另外一個數據流。
readStream.on('open',function(){
readStream.pipe(writeStream);
})
>> http模塊
var http = require('http');
var server = http.createServer(listener);
server.listen(post, host, callback)
response.writeHead(200,{'content-type':'text/html'});
response.write('welcome');
response.end('to homepage');
request對象:
request.url:發出請求的網址。
request.method:HTTP請求的方法。
request.headers:HTTP請求的全部HTTP頭信息。
當客戶端採用POST方法發送數據時,服務器端能夠對data和end兩個事件,設立監聽函數。
var listener = function(req, res){
var content = '';
res.on('data',function(chunk){
content += chunk;
});
res.on('end', function(){
res.writeHead(200, {'content-type':'text/plain'});
res.write(content);
res.end();
});
};
> http.request()方法 (也能夠理解成 http的client模式)
var options = {
host:'www.cnblogs.com',
path: "/stephenykk/"
/*,port:'80'
,method:'POST'
,headers:{header-name:header-val,..}*/
};
var callback = function(response) {
var str = '';
response.on('data', function(chunk){
str += chunk;
});
response.on('end', function(){
console.log(str);
});
};
var req = http.request(options, callback);
req.write('hello world!');
req.end();
>> 搭建HTTPs服務器
搭建HTTPs服務器須要有SSL證書。對於向公衆提供服務的網站,SSL證書須要向證書頒發機構購買;對於自用的網站,能夠自制。
自制SSL證書須要OpenSSL,生成兩個文件:ert.pem(證書文件)和 key.pem(私鑰文件)。有了這兩個文件,就能夠運行HTTPs服務器了。
var http = require('http');
var fs = require('fs');
var options = {
key: fs.readFileSync('key.pem'),
cert:fs.readFileSync('cert.pen')
};
var server = http.createServer(options, function(req, res){
res.writeHead(200);
res.end('hello world!');
}).listen(443);
>> events模塊
events模塊是node.js對「發佈/訂閱」模式(publish/subscribe)的部署。也就說,經過events模塊的EventEmitter屬性,創建一個消息中心;而後經過on方法,爲各類事件指定回調函數,從而將程序轉爲事件驅動型,各個模塊之間經過事件聯繫。
var EventEmitter = require('events').EventEmitter;
var emitter = new EventEmitter();
emitter.on('someEvent',function([data]){...}); //註冊事件監聽
emitter.once('someEvent',function(){ ..}) //監聽事件 回調只執行一次
emitter.emit('someEvent', [data]); //觸發事件
emitter.removeListener('someEvent', foo); //取消事件監聽
emitter.removeAllListeners('someEvent');//移除 someEvent 的全部回調
emitter.removeAllListeners(); //移除全部事件的全部回調
emitter.listeners('someEvent'); //返回事件回調函數的數組
默認狀況下,Node.js容許同一個事件最多能夠觸發10個回調函數。超過10個回調函數,會發出一個警告。這個門檻值能夠經過setMaxListeners方法改變。
emitter.setMaxListeners(20);
events模塊默認支持一些事件: newListener, removeListenernewListener事件:添加新的回調函數時觸發。removeListener事件:移除回調時觸發。emitter.on('newListener', function(eventName){ console.log("new listener:" + eventName);});emitter.on('removeListener', function(eventName){ console.log("remove listener:" + eventName);});