包括加载失败的库的本地版本

Including a local version of a library that failed to load

我使用 PhantomJS 每五分钟截取一个页面的屏幕截图,大部分时间都可以正常工作。问题是有时我正在截屏的页面无法加载 AngularJS 库,然后,它无法在此之后构建页面。所以我想弄清楚如何在其位置加载本地副本。这是我一直在尝试的...

var page = require('webpage').create(),system = require('system');
var home = 'https://smartway.tn.gov/traffic/';

page.open(home, function (status) {
    if(status === "success"){
        page.injectJs('angular.js');
        window.setTimeout((function() {
            page.evaluate(function () {
                /*stuff*/
            });
        }), 2000);
    }
});

所以 angular.js 是该网站通常下载的我的本地副本的名称。该站点用其他几个脚本调用正文末尾的脚本,我正在尝试找到包含它的最佳方法。我想知道是否需要通过替换 html 中的脚本标记来包含它,以便它可以按顺序加载,但我不确定该怎么做。

谢谢

在失败时重新加载单个 JavaScript 文件是有问题的,尤其是当它是框架时。可能有很多依赖于它的脚本。当核心框架未加载时,这些脚本将停止执行,因为无法解析 angular 引用。

可以 注入 angular 的本地版本,但是您必须检查所有其他引用 angular 和 "reload" 通过按顺序下载和 evaling 它们或将它们作为脚本元素放入页面。我反对它,因为它可能很容易出错。

如果页面加载后 angular 不存在,您应该重新加载页面(page.open 的回调)。由于重新加载时可能会出现同样的问题,因此必须递归完成:

function open(countDown, done){
    if (countDown === 0) {
        done("ERROR: not loaded");
        return;
    }
    page.open(home, function (status) {
        if(status === "success"){
            var angularExists = page.evaluate(function () {
                return !!angular;
            });
            if (angularExists){
                done();
            } else {
                open(countDown - 1, done);
            }
        } else {
            open(countDown - 1, done);
        }
    });
}
open(5, function(err){
    if(err) {
        console.log(err);
    } else {
        page.render(target);
    }
});

您也可以尝试使用 page.reload() 函数代替 page.open()


另一种可能性是在页面加载开始时始终注入本地版本并停止对脚本的远程版本的任何请求:

page.onLoadStarted = function() {
    page.injectJs('angular.js');
};
page.onResourceRequested = function(requestData, networkRequest) {
    var match = requestData.url.match(/angular\.min\.js/g);
    if (match != null) {
        networkRequest.abort(); 
    }
};
page.open(home, function (status) {
    if(status === "success"){
        window.setTimeout((function() {
            page.evaluate(function () {
                /*stuff*/
            });
        }), 2000);
    }
});

此版本无需重新加载即可完全运行。