简体   繁体   中英

Including a local version of a library that failed to load

I am using PhantomJS to take a screenshot of a page every five minutes, and it works correctly most of the time. The problem is that sometimes the page I am taking a screenshot of fails to load the AngularJS library, and then, it can't build the page after that. So I am trying to figure out how to load a local copy in its place. Here is what I have been trying...

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);
    }
});

So angular.js is the name of my local copy of what the site would normally download. The site calls the script at the end of the body with several other scripts, and I am trying to find the best way to include it. I am wondering if it needs to be included by replacing the script tag in the html so it can be loaded in sequence, but I am not sure how to do that.

Thanks

It is problematic to reload a single JavaScript file when it failed, particularly when it is the framework. There are probably many scripts which depend on it. When the core framework is not loaded, those scripts will stop executing, because the angular reference cannot be resolved.

You could inject a local version of angular, but then you would have to go over all the other scripts which reference angular and "reload" them by either downloading and eval ing them in order or putting them into the page as script elements. I advise against it, because it is probably very error prone.

You should just reload the page if angular does not exist after page load (callback of page.open ). Since the same problem may occurr during reload, this has to be done recursively:

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);
    }
});

You can also try the page.reload() function instead of a page.open() .


The other possiblity is to always inject the local version when the page loading began and stop any request for the remote version of the script:

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);
    }
});

This version works entirely without reloading.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM