【问题标题】:PhantomJS: How to access global functions and variables?PhantomJS:如何访问全局函数和变量?
【发布时间】:2018-04-06 12:52:48
【问题描述】:

我正在尝试通过 PhantomJS 运行 .js 并使用页面上下文中的一些全局函数或变量。

这是一个最小的例子:

var page = require('webpage').create(); // or: var page = new WebPage();

// reroute page's console to global console
page.onConsoleMessage = function(msg) { console.log(msg) }

function Foo(x) { return "bar"+x }

page.open( 'https://www.example.com/', function(){

    console.log(Foo(1)); // works OK

    page.evaluate( function(){

        console.log('test'); // works OK (message appears because we rerouted 
                             // the page's console to global console output)

        console.log(Foo(2)); // does NOT work, Foo is unknown
    });

    console.log(Foo(3)); // works OK
    phantom.exit();

});

注意Foo() 函数在页面的evaluate() 函数的上下文中是如何未知的。

我尝试了很多方法,例如在Foo 的定义下方执行page.Foo2 = Foo;,然后在evaluate 上下文中调用Foo2(2),但没有。

page.Foo2 = function(x) { return Foo(x) },但同样无济于事。也不要通过调用this.Foo2(2) 而不仅仅是Foo2(2)(如果这甚至有意义的话)。

如何访问page 范围之外的函数或变量?

【问题讨论】:

    标签: javascript scope phantomjs global globals


    【解决方案1】:

    您可以在沙盒上下文中声明一个函数:

    page.open( 'https://www.example.com/', function(){
    
        page.evaluate( function(){
    
            function Foo(x) { return "bar"+x }
    
            console.log(Foo(2));
        });
    
        phantom.exit();
    });
    

    或者,如果您也需要在全局上下文中使用它,您可以将其发送到沙箱中:

    function Foo(x) { return "bar"+x }
    
    page.open( 'https://www.example.com/', function(){
    
        console.log(Foo(1));
    
        page.evaluate( function(Foo){
    
            console.log(Foo(2));
    
        }, Foo);
    
        console.log(Foo(3));
    
        phantom.exit();
    });
    

    【讨论】:

    • 是的,但这不是我需要的,我有全局函数,我也想从页面/沙箱上下文中调用它们。
    • 谢谢,但不,在大多数情况下,我不能简单地在页面范围内重新声明相同的功能。例如,如果我想这样做:var f = require('fs').open('test.txt','w'); f.write('hello'); f.close(); 来写一个文本文件。这适用于 page.evaluate,但不适用于内部(不知道 require)。这里我只写了“hello”,但假设我想保存页面的 html 内容或其他我只能在 page.evaluate 中获取的内容。
    • 您应该在问题中更好地解释您的意图。当然浏览器不能f.write,但是您可以将这样的功能传递给沙箱并从那里使用它。所以,从技术上讲,答案是正确的(至少考虑到这个问题)。
    • 至于你想要什么,为什么还要这么做?为什么不直接从page.evaluate 获取数据并在全局上下文中将其写入磁盘?
    • 是的,在这个特殊的最小示例中,我可以只输出结果。如果我想从评估沙箱中写入或附加更复杂的数据,这不适用。或者做一些除了写文件之外的事情,比如发送像page.sendEvent('keypress',page.event.key.Return)这样的按键事件。现在我只能从外部执行此操作,但由于某种原因,我无法将f(文件)对象或page 对象或sendEvent 函数闭包传递到沙箱中。我什至很惊讶您可以传递简短的示例 Foo 函数,但如果 Foo 调用其他“外部”函数,这将不起作用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-04
    • 2021-05-17
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    • 2011-05-31
    相关资源
    最近更新 更多