我有一个CasperJS脚本,它的结果需要在PHP中捕获。为此,我必须使用PHP的exec()
或shell_exec()
函数。但最近我知道在服务器上启用命令行执行是有风险的,而且不安全。那么我应该如何运行我的CasperJS脚本不使用这些函数中的任何一个在PHP?
p :更确切地说,如何在web浏览器上使用CasperJS,比如用PHP处理web表单,并返回从CasperJS派生的输出,而不需要触摸exec或shell_exec来执行它。
CasperJS是建立在PhantomJS(或SlimerJS)之上的。它可以使用PhantomJS提供的所有功能,包括Web服务器模块。我们的想法是运行一个CasperJS实例,PHP脚本可以通过HTTP查询。
您可以在系统启动时或通过cron作业启动CasperJS脚本(并在它崩溃时重新启动)。然后,您可以通过本地http请求查询它。
CasperJS脚本:
var webserver = require('webserver');
var server = webserver.create();
var service = server.listen(8080, function(request, response) {
var casper = require('casper').create({
exitOnError: false,
onError: function(msg, backtrace){
response.statusCode = 500;
response.write('ERROR: ' + msg + "'n" + JSON.stringify(backtrace));
response.close();
}
});
casper.start(yourURL, function(){
// TODO: do something
response.statusCode = 200;
response.write('something');
response.close();
}).run(function(){
// this function is necessary to prevent exiting the whole script
});
});
在PHP中,你可以使用file_get_contents()
来检索响应:
$result = file_get_contents("http://localhost:8080/");
注意事项:
- 配置你的机器,使PhantomJS运行的端口不能从外部访问。
- 如果您使用cron作业方法,请编写pid文件以确保不启动另一个实例。
- web server模块只支持10个并发请求。如果您的系统超过了这些,您将需要创建多个CasperJS (PhantomJS)进程池。
- 单个CasperJS (PhantomJS)进程的页面都像在任何普通浏览器中一样共享相同的会话。如果你想将它们彼此隔离,那么你需要为每个请求运行一个CasperJS (PhantomJS)进程。
你跳平常的方块舞
- 运行你的PHP程序,捕获输入,生成一个作业配置。
- 把作业放到你的数据库中,用CRON把它取出。
- 用处理,把结果放在不同的DB表中,或者放在文件系统中。
- 将作业标记为'done',这样面向用户的PHP可以定期轮询该状态,并在完成时向用户呈现最终结果。
如果你这样做是因为你知道exec()
在你的应用程序中暴露了什么攻击向量,并且不能忍受——那没关系。
但如果你这样做是因为你害怕"甚至不确定",那就不要这样做。你会让事情变得更糟的。
好运。
:)