Check if my javascript is loaded on a site

后端 未结 3 853
我在风中等你
我在风中等你 2020-12-22 00:57

I have asked this question before but it seems i got misunderstood therefore i decided to ask again but this time with alot of information:

For the lazy reader my go

相关标签:
3条回答
  • 2020-12-22 01:51

    A roundabout or rather a naive way would be create a dummy object definition with a unique name say 'your_company_name_'+some_hash. like abc_45xcd.

    //your custom js file
    
    //BEWARE! this is global namespace. 
    
    function abc_45xcd(){
          console.log('abc_45scd custom js is loaded');
    }
    

    When you click test button you can try creating a new object

       var x = new abc_45scd();
    

    You can check the constructor and type for checking if its your 'own' custom dummy object.

    Note: This is actually a naive solution, as some one might create an object of same name in their script. Also, it pollutes global namespace for no reason.

    0 讨论(0)
  • 2020-12-22 01:58

    Is it possible to check if a site has a certain JavaScript?

    You could do two things, where I think the one using JavaScript would be easier to implement.

    Using PHP:

    • fetch the content from the URLs in your database
    • load it into a DOMDocument and search for a specific part of your code
    • extract all external JavaScript files from that document
      • fetch them too and search for a specific code part within

    Using JavaScript

    • implement an AJAX request within a constructor or an initiate method
    • send the current domain where the script is executed and compare it to the list in your database

    Self hosting

    • as discussed while writing this answer, this is another possibility, as your log can show all pages that this script accessed

    Is it possible to check if the javascript is running without errors?

    This one is a bit more complicated as you have check this during runtime. Imagine the user of your script extends or modifies your code or simply uses it in a wrong way or has something that conflicts with your code. Maybe this code is never reached, as it invokes some user interaction, that may or may not be triggered.

    One possibility would be to send an AJAX request back to you, when an error occured. You can check out window.onerror for that purpose:

    window.onerror = function(message, url, lineNumber) {}
    

    This will give you some detailed information, that you can pass to your server using an AJAX request.

    0 讨论(0)
  • 2020-12-22 01:59

    I'll post it here, too. Since I was the guy that put you on to phantomjs, it's only fair to provide you with, what I think, is the answer to your problems.
    The following script opens a page in the headless phantom browser, logs any console messages that page would yield in an actual browser, (using the onConsoleMessage event), it also logs the error if the page were to be unable to load, and, if the page was opened without issues, it checks all <script> tags on that page, looking for your javascript file.

    var page = require('webpage').create();
    page.onConsoleMessage = function( message, line, srcId)
    {//show console errors for page
        console.log('Page has errors showing in console: ' + msg
                    + ' (line: ' + (line || '?') + ', id: ' + srcId + ')');
    };
    page.open('http://www.your-url-here.org',function(status)
    {
        if (status != 'success')
        {//can't load page
            console.log('Failed to open page: ' + status);
            phantom.exit();
            return;
        }
        var reslt = page.evaluate(function()
        {
            var usesOurScript = false,
            scripts = document.querySelectorAll('script');//get all script tags
            /* Array.forEach is causing errors, as it turns out...
            Array.forEach.apply(scripts, [function(elem)
            {//check all loaded scripts
                if (/yourScriptName\.js/.test(elem.getAttribute('src')))
                {//this src attribute refers your script
                    usesOurScript = true;//set to true
                }
            }]);*/
            for (var i=0;i<scripts.length;i++)
            {
                if (/yourScriptName\.js/.test(scripts[i].getAttribute('src')))
                {
                    return {page: location.href, found: true};
                }
            }
            return {page: location.href, found: false};
        });
        //script was found? adjust message
        reslt.found = (reslt.found ? ' uses ' : ' does not use ') + 'our script!';
        console.log(reslt.page + reslt.found);//logs url does not use || uses our script
        phantom.exit();
    });
    

    If that file is does something like jQ (create a global reference to some object) you might even add this to the page.evaluate callback:

        var reslt = page.evaluate(function()
        {//this code will behave like it's running on the target page
            var libs = {jQuery: ($ || jQuery),
                        myLib: ourLibsGlobalName};
            return libs;
        });
        if (reslt.jQuery instanceof Object)
        {
            console.log('client uses jQ');
        }
        if (reslt.myLib instanceof Object)
        {
            console.log('client uses our lib, successfuly');//wouldn't be accessible if it contained errors
        }
        console.log(reslt.myLib);//shows full object, so you can verify it's the right one
    

    Note:
    This code is un-tested, I just wrote it off the top of my head. It may contain silly typo's. It's not a copy-pastable answer to all of your prayers.
    I do believe the page.evaluate callback is able to return something, however: it's running in the context of the loaded page, and is sandboxed, so you may have to force an error:

    page.evaluate(function()
    {
        Array.forEach(document.querySelectorAll('script'), [function(elem)
        {
            if (/yourScript\.js/.test(elem.getAttribute('src')))
            {
                throw {message: 'Script found',
                       nodeSrc: elem.getAttribute('src'),
                       pageUrl: location.href,
                       myLib  : yourGlobalVar}//<-- cf remarks on jQ-like usage
            }
        }]);
    });
    

    By throwing this custom error, which isn't being caught, so it'll end up in the console, you force the page.onConsoleMessage handler to deal with this exception. That could be a way around the sandbox restrictions, in a way, if they're causing the infinite loop issue to occur.

    0 讨论(0)
提交回复
热议问题