phantomjs實現(xiàn)了一個無界面的webkit瀏覽器尤勋。雖然沒有界面,但dom渲染茵宪、js運行最冰、網(wǎng)絡(luò)訪問、canvas/svg繪制等功能都很完備稀火,在頁面抓取锌奴、頁面輸出、自動化測試等方面有廣泛的應(yīng)用憾股。
安裝
下載phantomjs( 官方下載 鹿蜀,下載失敗請訪問 另一個下載點 )。解壓到任意目錄服球,并將包含phantomjs.exe的目錄添加到系統(tǒng)路徑茴恰。
如果要借助phantomjs進行無頭測試,請參考各個測試框架的說明斩熊,或者參考phantomjs的官方文檔: http://phantomjs.org/headless-testing.html 往枣。
使用說明
簡單示例
// test.js var page = require('webpage').create(), system = require('system'), address; if (system.args.length === 1) { phantom.exit(1); } else { address = system.args[1]; page.open(address, function (status) { console.log(page.content); phantom.exit(); }); }
運行:
phantomjs ./test.js http://baidu.com
這個例子簡單地展示了通過phanton訪問baidu.com,并輸入html內(nèi)容粉渠。使用方式就像使用node運行js代碼一樣分冈。在phantom運行時,它會向當前代碼運行環(huán)境注入phantom對象霸株。如上面代碼中雕沉,通過phantom對象控制程序終結(jié)。示例中其他代碼的含義以及更多深入的用法去件,將在下文中展開坡椒。
window對象
在使用phantom時,我首先關(guān)注的是DOM和BOM接口尤溜。不過這不是一個問題倔叼,看了下面的代碼就能了解:
// test.js console.log(window === this); phantom.exit();
運行:
phantomjs ./test.js
結(jié)果為 true
。也就是說宫莱,就像瀏覽器環(huán)境一樣丈攒,我們的代碼運行在window環(huán)境下,可以很方便地進行DOM方面的操作。
注:如果使用web page模塊打開頁面巡验,則請不要在此window對象下進行任何DOM相關(guān)的操作识椰,因為這個window并不是page對象內(nèi)的window。如果想要執(zhí)行dom相關(guān)操作深碱,請參閱 page.evaluate()
部分腹鹉。
phantom對象
之前的例子中我們已經(jīng)初步認識了phantom對象。它的功能是定義和控制phantom運行環(huán)境的參數(shù)和流程敷硅。關(guān)鍵的API有:
phantom.args
String[]
獲取傳給本JS程序的參數(shù)功咒,需要與 system.args
進行區(qū)分(system模塊詳見下文),后者表示傳給phantomjs引擎的參數(shù)绞蹦。例如 phantomjs ./test.js http://baidu.com
這句語句鸦致,通過 phantom.args
盆犁,我們能得到的參數(shù)列表為 ["http://baidu.com"]
冗懦,而通過 system.args
則得到 ["./test.js", "http://baidu.com"]
這樣的參數(shù)列表离福。差異就在于是否包含當前腳本名稱。不過 phantom.scriptName
這個API提供了獲取腳本名稱的功能澡屡。
phantom.cookies
Object[]
獲取或設(shè)置cookies猿挚,不過對于設(shè)置建議使用其他的API完成。同時相關(guān)的API還有:
phantom.addCookie(Object)
Boolean:添加cookie值
phantom.deleteCookie(cookieName)
Boolean:刪除指定Cookie值
phantom.clearCookies()
:清空所有的cookie
phantom.cookiesEnabled
Boolean:獲取或設(shè)置是否支持cookie
phantom.injectJs(fileName)
Boolean:
把指定的外部JS文件注入到當前環(huán)境驶鹉。執(zhí)行這個方法時绩蜻,phantomjs首先會從當前目錄檢索此文件,如果找不到室埋,則再到 phantom.libraryPath
指定的路徑尋找办绝。 phantom.libraryPath
這個API基本上就是為 phantom.injectJs()
服務(wù)的。
phantom.onError
當頁面存在js錯誤姚淆,且沒有被 page.onError
處理孕蝉,則會被此handler捕獲。下面是使用此API的一個例子腌逢。由于phantom環(huán)境下代碼調(diào)試很困難降淮,了解這些錯誤捕獲的API也許會對我們的實際使用有所幫助。
phantom.onError = function(msg, trace) { var msgStack = ['PHANTOM ERROR: ' + msg]; if (trace && trace.length) { msgStack.push('TRACE:'); trace.forEach(function(t) { msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : '')); }); } console.error(msgStack.join('\n')); phantom.exit(1); };
phantom.exit(returnValue)
這個API已經(jīng)見過多次了上忍,它的作用是退出程序骤肛,可以設(shè)置一個退出代碼纳本,默認是0窍蓝。
web page 模塊
web page模塊的功能是處理具體的頁面。使用時需要引入模塊繁成,并創(chuàng)建實例:
var webPage = require('webpage'); var page = webPage.create();
本文中不經(jīng)說明吓笙, page
指代 require("webpage").create()
的實例。
page.cookies
Object[]
與上文中的 phantom.cookies
類似巾腕,表示本url下的cookie的讀取面睛。同樣類似的API還有 addCookie()
絮蒿、 deleteCookie()
、 clearCookies()
叁鉴。
頁面內(nèi)容相關(guān)的API
page.content
String:獲取或設(shè)置當前頁面的html土涝。
page.plainText
String:這是一個只讀屬性,獲取頁面去除html標記的文本(考慮 $.text()
)幌墓。
page.url
String:只讀但壮,獲取當前頁面的url。
page.setContent()
:允許修改 page.content
和 page.url
內(nèi)容常侣,會觸發(fā)reload蜡饵。
page.settings
Object
對于當前頁面的一些配置項。此API必須在 page.open()
調(diào)用之前設(shè)置胳施,否則不會起作用溯祸。以下是配置項: * javascriptEnabled
默認 true
:是否執(zhí)行頁面內(nèi)的javascript
loadImages
默認 true
:是否載入圖片
userAgent
:傳遞給服務(wù)器的userAgent字符串
userName
:用于http訪問授權(quán)的用戶名
password
:用于http訪問授權(quán)的密碼
XSSAuditingEnabled
默認 false
:是否監(jiān)控跨域請求
resourceTimeout
單位 ms
:定義資源請求的超時時間。如果設(shè)置了此項舞肆,則頁面中如果有任何資源超過此時限未請求成功焦辅,則頁面其他部分也會停止請求,并觸發(fā) onResourceTimeout()
事件處理椿胯。
page.customHeaders
Object
phantom允許在請求時在http請求頭部添加額外信息氨鹏,此設(shè)置項對這個page里面所有的請求都生效(包含頁面和其他資源的請求)。添加的信息并沒有限制压状,但如果設(shè)置 User-Agent
的值仆抵,那么這個值會覆蓋掉 page.settings
里的設(shè)置值。示例:
page.customHeaders = { "X-Test": "foo", "DNT": "1" };
page.libraryPath
String
與 phantom.libraryPath
類似种冬,page對象也支持設(shè)置js文件路徑镣丑,同時可以通過相應(yīng)的 page.injectJs()
方法注入javascript文件。除了 page.injectJs()
方法外娱两,還有 page.includeJs()
也可以加入javascript文件莺匠。它們的區(qū)別在于, page.injectJs()
不強求此文件能訪問得到十兢,即使是一個不可訪問的資源也可以趣竣。
page.navigationLocked
Boolean 默認 fasle
設(shè)置是否允許離開當前頁面,默認是允許旱物。
page.open()
此方法用于打開一個網(wǎng)頁遥缕,是一個很重要的API,它有三種調(diào)用形式:
open(url, callback)
open(url, method, callback)
open(url, method, data, callback)
聯(lián)想一下 $.ajax()
宵呛,可以更好理解這個API单匣。對于這些參數(shù),需要單獨闡述的是 callback
。 callback()
會在頁面載入完成后調(diào)用户秤,由 page.onLoadFinished
調(diào)用(時機晚于 page.onLoadFinished
)码秉。這個 callback
會接受一個參數(shù) status
,可能值為 "success"
和 "fail"
鸡号,指示頁面是否加載成功转砖。示例可以參考“簡單示例”一節(jié)的例子。
page.close()
與 page.open()
對應(yīng)鲸伴,調(diào)用 page.close()
之后堪藐,會釋放page所占用的內(nèi)存,我們不可以在此之后再調(diào)用page實例挑围。在實際的操作中礁竞,調(diào)用此方法并不會完成清空所占內(nèi)存;javascript的垃圾回收機制也不會回收page實例杉辙。但在實際使用中模捂,常常會遇到將一個page實例反復(fù)open的情況。在一個頁面用完后蜘矢,記得一定要執(zhí)行 page.close()
狂男,這樣在下一次open的時候,才不會重復(fù)分配堆椘犯梗空間岖食。
page.evaluate(fn, [param])
對于page打開的頁面,往往需要與其進行一些交互舞吭。 page.evaluate()
提供了在page打開頁面的上下文(下文直接用page上下文指代)執(zhí)行function的功能(類比Chrome開發(fā)者工具的控制臺)泡垃。如下例:
page.open('http://m.bing.com', function(status) { var title = page.evaluate(function(s) { return document.querySelector(s).innerText; }, 'title'); console.log(title); phantom.exit(); });
在這個例子中, page.evaluate()
接受兩個參數(shù)羡鸥,第一個是必需的蔑穴,表示需要在page上下文運行的函數(shù) fn
;第二個是可選的惧浴,表示需要傳給 fn
的參數(shù) param
存和。 fn
允許有一個返回值 return
,并且此返回值最終作為 page.evaluate()
的返回值衷旅。這邊對于剛剛命名的 param
和 return
有一些額外的說明和注意事項捐腿。對于整個phantom進程而言, page.evaluate()
是跑在一個沙盒中柿顶, fn
無法訪問一切phantom域中的變量茄袖;同樣 page.evaluate()
方法外部也不應(yīng)該嘗試訪問page上下文中的內(nèi)容。那么如果兩個作用域需要交換一些數(shù)據(jù)九串,只能依靠 param
和 return
绞佩。不過限制很大寺鸥, param
和 return
必須為能夠轉(zhuǎn)化為JSON字符串猪钮,換言之品山,只能是基本數(shù)據(jù)類型或者簡單對象,像DOM 節(jié)點烤低、$對象肘交、function、閉包等就無能為力了扑馁。
這個方法是同步的涯呻,如果執(zhí)行的內(nèi)容對后續(xù)操作不具備前置性,可以嘗試異步方法以提高性能: page.evaluateAsync()
腻要。
page.render(filename)
page.render()
能夠把當前頁面渲染成圖片并輸出到指定文件中复罐。輸出的文件格式由傳入的文件擴展名決定,目前支持 PNG
雄家、 JPEG
效诅、 GIF
、 PDF
趟济。
var page = require('webpage').create(); page.open('http://github.com/', function() { page.render('github.png'); phantom.exit(); });
還有其他一些API會對 page.render()
產(chǎn)生影響乱投,如:
page.zoomFactor
Number: 設(shè)置縮放比率
page.clipRect
Object:設(shè)置輸出的矩形區(qū)域,例如:
page.clipRect = { top: 14, left: 3, width: 400, height: 300 };
還有一些頁面設(shè)置參數(shù)顷编,如果紙張大小戚炫,側(cè)邊距等,在此不詳述媳纬。web page也支持輸出圖片base64格式的字符串双肤,API為 page.renderBase64()
,也不再詳述钮惠。
page.sendEvent()
為了交互的需要(測試的需要)杨伙,phantom允許通過代碼模擬一些交互事件(注意與DOM事件的區(qū)分)。
鼠標事件:
API: sendEvent(mouseEventType[, mouseX, mouseY, button='left'])
mouseEventtype
可能的取值為: 'mouseup'
萌腿、 'mousedown'
限匣、 'mousemove'
、 'doubleclick'
和 'click'
毁菱,這個參數(shù)為必須的米死。
后兩個參數(shù)為鼠標事件的坐標位置。最后一個參數(shù)為鼠標按鍵贮庞,只對需要按鍵的事件有效峦筒,默認為 'left'
,可能值為 'right'
窗慎、 'left'
物喷、 'middle'
卤材。
鍵盤事件:
API: sendEvent(keyboardEventType, keyOrKeys, [null, null, modifier])
keyboardEventType
可能的取值為 'keyup'
、 'keydown'
峦失、 'keypress'
扇丛,第2個參數(shù)傳入一個鍵值或一個字符串。鍵值可以通過 page.event.key
來查詢調(diào)用尉辑。第三和第四個參數(shù)無效帆精,第五個參數(shù)表示同時按下的修飾鍵。取值情況如下:
: 未使用修飾鍵
0x02000000
: Shift鍵被按下
0x04000000
: Ctrl鍵被按下
0x08000000
: Alt鍵被按下
看一個示例:
page.sendEvent('keypress', page.event.key.A, null, null, 0x02000000 | 0x08000000);
page.switchToFrame(frameName/framePosition)
默認page對應(yīng)的是frame隧魄,如果一個頁面中還有其他frame卓练,則可以通過此方法切換page對應(yīng)的frame。其他類似的方法還有 switchToChildFrame()
购啄、 switchToParentFrame()
襟企、 switchToFocusedFrame()
、 switchToMainFrame()
等狮含,不再贅述顽悼。
page.uploadFile(selector, file)
頁面中常常會有上傳文件的操作,但phantom沒有界面辉川,因而也就沒有辦法選擇文件上傳表蝙,通過此方法可以模擬文件上傳操作。示例如下:
page.uploadFile('input[name=image]', '/path/to/some/photo.jpg');
一些事件處理接口
page.onAlert
:phantom沒有界面乓旗,所以也就不能處理alert窗口府蛇,但可以通過此接口捕獲到alert。
page.onPrompt
:類似的屿愚,phantom不能處理prompt窗口汇跨,通過這個接口可以捕獲prompt。
page.onConfirm
:類似的妆距,phantom不能處理confirm窗口穷遂,通過這個接口可以捕獲confirm。
page.onConsoleMessage
:類似的娱据,phantom不能顯示console窗口蚪黑,通過這個接口可以捕獲console消息。
var webPage = require('webpage'); var page = webPage.create(); page.onAlert = function(msg) { console.log('ALERT: ' + msg); }; page.onPrompt = function(msg, defaultVal) { if (msg === "What's your name?") { return 'PhantomJS'; } // 返回值就是prompt得到的值 return defaultVal; }; page.onConfirm = function(msg) { console.log('CONFIRM: ' + msg); // 返回true相當于點擊“確定”中剩,返回false相當于點擊“取消” return true; }; page.onConsoleMessage = function(msg, lineNum, sourceId) { console.log('CONSOLE: ' + msg + ' (from line #' + lineNum + ' in "' + sourceId + '")'); };
page.onInitialized
:在page創(chuàng)建后觸發(fā)忌穿。
page.onUrlChanged
:在url發(fā)生變化時觸發(fā)。它接受新的url作為參數(shù)结啼。首次加載頁面掠剑, page.onUrlChanged
是在 page.onInitialized
之后觸發(fā)。
page.onNavigationRequested
:如果在 page.navigationLocked
中允許頁面跳轉(zhuǎn)郊愧,此接口才會有意義(參見 page.navigationLocked
)朴译。它接受4個參數(shù)井佑,先看示例:
page.onNavigationRequested = function(url, type, willNavigate, main) { console.log('Trying to navigate to: ' + url); console.log('Caused by: ' + type); console.log('Will actually navigate: ' + willNavigate); console.log('Sent from the page\'s main frame: ' + main); }
url
表示要跳轉(zhuǎn)到的url
type
表示產(chǎn)生跳轉(zhuǎn)的原因,可能值有
'Undefined'
眠寿、
'LinkClicked'
躬翁、
'FormSubmitted'
、
'BackOrForward'
澜公、
'Reload'
姆另、
'FormResubmitted'
喇肋、
'Other'
willNavigate
表示是否會跳轉(zhuǎn)坟乾,由
page.navigationLocked
控制
main
表示發(fā)生跳轉(zhuǎn)的是否是主frame,如果是主frame則為true蝶防,如果為其他frame則為false
page.onLoadStarted
:在開始載入資源時觸發(fā)甚侣。
page.onLoadFinished
:頁面所有資源載入完成后觸發(fā)。其實與 page.open()
的回調(diào)函數(shù)等價间学。它接受一個參數(shù) status
殷费,表示加載是否成功。參見 page.open()
低葫。
page.onClosing
:當在phantom域調(diào)用 page.close()
或page上下文調(diào)用 window.close()
時觸發(fā)详羡。
page.onError
: 此接口捕獲所有page上下文發(fā)生的javascript錯誤。參數(shù)是錯誤信息和調(diào)用堆棧嘿悬,參見 phantom.onError
实柠。如果page不處理錯誤,那么這些錯誤會冒泡到phantom的onError處理器善涨。
page.onCreate
:當page創(chuàng)建子窗口時觸發(fā)窒盐,例如在page上下文中使用 window.open
,但是子窗口再創(chuàng)建子窗口不會觸發(fā)此事件钢拧。
page.onResourceRequested
:當頁面請求一個資源時觸發(fā)的事件蟹漓,它接受兩個參數(shù),第一個參數(shù)是 requestData
對象源内,它有如下屬性:
id
: 資源請求編號
method
: http請求方法葡粒,get/post等
url
:請求的URL
time
: 一個Date object,包含響應(yīng)接收的時間
headers
: http頭部的信息列表
第二個參數(shù)是 networkRequest
實例膜钓,它包含3個方法:
* `abort()`:中斷當前的請求嗽交。這樣做會觸發(fā)onResourceError
* `changeUrl(url)`:改變當前請求的目標url
* `setHeader(key, value)`:修改/添加http頭部信息
page.onResourceReceived
:當一個資源請求的響應(yīng)接收到后觸發(fā)此事件,它接受一個 response
對象呻此,這個對象有如下屬性:
id
: 資源請求編號
url
:請求的URL
time
: 一個Date object轮纫,包含響應(yīng)接收的時間
headers
: http頭部的信息列表
bodySize
: 已接收到的數(shù)據(jù)大小(全部數(shù)據(jù)或已接收的部分數(shù)據(jù))
contentType
: 指定的內(nèi)容類型
redirectURL
: 如果是一個重定向響應(yīng)焚鲜,那么此處是重定向到的url
stage
: “start”/ “end”
status
: http狀態(tài)碼掌唾,如:200
statusText
: http狀態(tài)描述放前,如:OK
page.onResourceError
:當資源加載失敗時,觸發(fā)此事件糯彬。它接收一個 resourceError
對象凭语,這個對象有如下屬性:
id
:資源請求的編號
url
:請求的URL
errorCode
:錯誤代碼
errorString
:錯誤信息
可參考如下示例:
page.onResourceError = function(resourceError) { console.log('Unable to load resource (#' + resourceError.id + 'URL:' + resourceError.url + ')'); console.log('Error code: ' + resourceError.errorCode + '. Description: ' + resourceError.errorString); };
page.onResourceTimeout
:在講
page.settings
時曾經(jīng)提到過這個事件。如果設(shè)置了
page.settings.resourceTimeout
撩扒,并且資源在這個時間內(nèi)沒有載入完成似扔,則會觸發(fā)此事件,它接受一個
request
對象搓谆,這個對象包含如下屬性:
id
: 資源請求編號
method
: http請求方法炒辉,get/post等
url
:請求的URL
time
: 一個Date object,包含響應(yīng)接收的時間
headers
: http頭部的信息列表
errorCode
:錯誤代碼
errorString
:錯誤信息
Child Process模塊
通過Child Process模塊泉手,我們能創(chuàng)建子進程黔寇,借助 stdin
、 stdout
斩萌、 stderr
來實現(xiàn)進程間通信(很C++)缝裤。使用子進程能夠做很多事情,如打印颊郎、發(fā)郵件憋飞、調(diào)用腳本或其他程序(不局限于javascript)。
要使用Child Process模塊姆吭,我們需要在代碼中添加 require("child_process")
榛做。
以下內(nèi)容缺乏文檔支持,并未經(jīng)過充分測試猾编,可能存在一定的理解偏差瘤睹。這部分功能是極有用的,希望在項目中使用的時候注意測試答倡。
Child Process模塊本身應(yīng)該也并完全開發(fā)完全轰传。 spawn()
、 execFile()
可用瘪撇, exec()
和 fork()
尚未實現(xiàn)获茬。
spawn(command, [args], [options])
最基本的創(chuàng)建進程的方法。前兩個參數(shù)比較重要倔既,例如現(xiàn)在想從phantom進程中運行一段nodejs腳本恕曲,腳本路徑為 “main.js”
,這個腳本接受一個參數(shù)渤涌,假定為 “helloworld”
佩谣,那么如果想得到這段腳本的運行結(jié)果應(yīng)該怎么做呢?參考下面的腳本:
var spawn = require("child_process").spawn; child = spawn('node', ['main.js', 'helloworld']); child.stdout.on("data", function (data) { console.log("spawnSTDOUT:", JSON.stringify(data)) }); child.stderr.on("data", function (data) { console.log("spawnSTDERR:", JSON.stringify(data)) }); child.on("exit", function (code) { console.log("spawnEXIT:", code) }); setTimeout(function () { phantom.exit(0) }, 2000);
其實 spawn()
方法沒什么神秘的实蓬,它就是運行第一個參數(shù)表示的命令茸俭,第二個參數(shù)就是這個命令的參數(shù)列表吊履。所以如果要開啟一個新的phantom進程,第一個參數(shù)為 phantom
就行调鬓。同樣的道理艇炎,指定好程序的路徑或者是腳本語言解釋器的路徑,通過這個方法可以做的事情很多腾窝。 比較不方便的是缀踪,進程間的通信只能通過 stdin
、 stdout
虹脯、 stderr
來完成驴娃,調(diào)用 spawn()
方法后,還需要對這些交互信息進行監(jiān)聽归形,上面的例子中演示了監(jiān)聽 stdout
和 stderr
的方法托慨。
execFile(cmd, args, opts, cb)
就像剛剛說的鼻由, spawn()
方法稍微感覺有點麻煩暇榴,使用 execFile()
能夠稍稍簡化上面的代碼。 execFile()
的前三個參數(shù)與 spawn()
的三個參數(shù)完全一樣蕉世,不同的是它多了一個 cb
回調(diào)函數(shù)蔼紧,看一個例子就知道這個回調(diào)函數(shù)有什么用了:
var execFile = require("child_process").execFile; child = execFile('node', ['main.js', 'helloworld'], null, function (err, stdout, stderr) { console.log("execFileSTDOUT:", JSON.stringify(stdout)) console.log("execFileSTDERR:", JSON.stringify(stderr)) }); setTimeout(function () { phantom.exit(0) }, 2000);
在 execFile()
中,對 stdout
狠轻、 stderr
的監(jiān)聽做了封裝奸例,簡化了我們的代碼,不過功能上與 spawn()
并無區(qū)別向楼。
file system模塊
雖然與node.js中文件系統(tǒng)模塊名稱和調(diào)用方法( require("fs")
)一樣查吊,但不得不說,phantom的文件系統(tǒng)模塊總體是比較簡單的湖蜕,API不多但夠用逻卖,API也不同于node.js的異步回調(diào)風格,而是采用stream+同步的風格昭抒,濃濃的C++風味评也。在使用的時間請一定要注意與node.js的文件系統(tǒng)模塊做區(qū)分。
fs.open(path, mode/opts)
File
open()
方法接受兩個參數(shù)灭返,第一個參數(shù)是要打開的文件路徑盗迟,第二個參數(shù)后面還會見到,這里統(tǒng)一說明熙含。如果是字符串罚缕,則代表文件打開的模式,可選的有 'r'
怎静、 'w'
邮弹、 'a/+'
喂饥、 'b'
(read時僅支持 'b'
);如果是一個對象肠鲫,則表示配置項员帮,一共有兩個配置項,分別是 mode
和 charset
导饲, mode
就是剛剛提到的打開模式捞高, charset
表示文件的編碼類型。參閱下面的示例:
var fs = require("fs"); var file = fs.open("main.js", 'r'); console.log(file.read()); file.close(); file = fs.open("main.js", 'a'); file.write("123"); file.close(); setTimeout(function () { phantom.exit(0) }, 2000);
對打開的文件渣锦,我們可以進行讀寫操作(具體使用與打開模式有關(guān))硝岗。如果對一個文件執(zhí)行了open,請別忘了在文件使用完成后袋毙,再對其執(zhí)行close型檀。
fs.read(path, mode/opts)
String
fs.read()
方法對文件讀取做了封裝,不必關(guān)心文件的打開關(guān)閉听盖,返回值為文件內(nèi)容胀溺。
fs.write(path, content, mode/opts)
fs.write()
方法對文件寫入做了封裝,不必關(guān)心文件的打開關(guān)閉皆看。
其他API:
fs.size(path)
Number:獲取文件大小
fs.copy(source, destination)
:復(fù)制文件
fs.copyTree(source, destination)
:復(fù)制目錄樹
fs.move(source, destination)
:移動文件
fs.moveTree(source, destination)
:移動目錄樹
fs.remove(file)
:刪除文件
fs.removeTree(path)
:刪除目錄
fs.join(partialPath[])
String:組合路徑
fs.split(path)
String[]:切割路徑
fs.exist(path)
Boolean:文件或目錄是否存在
fs.isFile(path)
Boolean:指定路徑是否是文件
fs.isDirectory(path)
Boolean:指定路徑是否是目錄
fs.list(path)
String[]:獲取指定目錄下的文件/目錄名稱列表
System模塊
在文檔一開始就已經(jīng)提到過system模塊仓坞,一開始的例子中,我們使用了system模塊提供的 args
屬性⊙鳎現(xiàn)在重新來認識一下system模塊无埃。system模塊主要管理著一些與運行環(huán)境有關(guān)的屬性。
system.args
String[]
獲取運行phantomjs時傳入的所有參數(shù)毛雇,這個不再贅述嫉称。
system.env
Object
獲取當前的環(huán)境信息。包含操作系統(tǒng)信息灵疮、環(huán)境變量信息等等织阅。通過下面的代碼來查看一下吧:
var system = require('system'); var env = system.env; Object.keys(env).forEach(function (key) { console.log(key + '=' + env[key]); }); setTimeout(function () { phantom.exit(0) }, 2000);
system.os
Object
獲取操作系統(tǒng)信息,返回一個簡單對象始藕,這個對象有3個屬性: architecture
:架構(gòu)蒲稳,如“32bit”; name
:操作系統(tǒng)名稱伍派; version
:操作系統(tǒng)版本江耀。
system.pid
Number
獲取當前進程的pid。
system.platform
String
永遠返回 'phantomjs'
Web Server模塊
phantomjs支持一個簡單的web server模塊诉植, require('webserver')
即可引入祥国。web server模塊基于 mongoose 。不過最好不要在生產(chǎn)環(huán)境使用這樣的服務(wù)器模塊,因為現(xiàn)階段此模塊僅允許10個并發(fā)請求舌稀。
看一個簡單的例子吧:
var webserver = require('webserver'); var server = webserver.create(); var service = server.listen(8080, function(request, response) { response.statusCode = 200; response.write('<html><body>Hello!</body></html>'); response.close(); });
首先需要創(chuàng)建服務(wù)器實例啊犬,然后調(diào)用 listen()
方法監(jiān)聽, listen()
方法的第一個參數(shù)可以為一個端口號壁查,也可以中 ip:port
這樣的ip+port組合方式觉至。第二個參數(shù)是處理請求的回調(diào)方法。下面描述一下 request
和 response
兩個對象睡腿。
request:
method
:http請求的方法语御,get、post等
url
: 包含http請求URL和get請求的query string(如果有的話)
httpVersion
:當前采用的http協(xié)議的版本
headers
:所有http請求頭部信息席怪,以鍵值對的形式提供
post
:請求主體应闯,僅對post和put方法的請求有效
postRaw
:如果Content-type為 'application/x-www-form-urlencoded'
(表單上傳的默認值)時,post的原始信息會暫存在此屬性中挂捻。
response:
headers
:以鍵值對的形式保存所有的HTTP請求頭部的信息碉纺,在第一次調(diào)用 write()
方法前一定要設(shè)置
setHeader(name, value)
:設(shè)置或添加特定的頭部信息
header(name)
:獲取特定的頭部信息
statusCode
:設(shè)置HTTP狀態(tài)碼
setEncoding(encoding)
: 標明傳給 write()
的數(shù)據(jù)需要轉(zhuǎn)換成什么格式,默認為UTF-8刻撒。如果數(shù)據(jù)為二進制字符串骨田,則設(shè)置為“binary”
write(data)
:向response中發(fā)送數(shù)據(jù)塊,可以多次調(diào)用
writeHead(statusCode, headers)
:向response中發(fā)送響應(yīng)頭部疫赎。 statusCode
是一個3位數(shù)字盛撑,表示HTTP狀態(tài)碼(如404)。后一個參數(shù)代碼響應(yīng)頭部
close()
:關(guān)閉HTTP連接
為了避免客戶端檢測到連接中斷捧搞,記得最后再用
write()
方法發(fā)送一個空字符串(如:
response.write("")
)。
closeGracefully()
:功能與 close()
一樣狮荔,不過更安全可靠胎撇,它能保證響應(yīng)頭部先發(fā)送,并自動在響應(yīng)最后加上 response.write("")