Check if my javascript is loaded on a site

萝らか妹 提交于 2019-12-29 09:22:05

问题


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 goal here is:

Is there a way to check if a javascript is enabled on an external site either from PHP or through Ajax

Detailed description:

Okay, so my company, has many clients, when these clients sign up on our website, they are handed a javascript. They can then use this script on their own website to get some extra features.

Now all of the websites, that a client has, is stored within our CMS system (like there is a list of all of the websites they have that are signed with us).

Now my boss gave me the following assignment:

We need a function so that the user can press the button "Test" and the system will test if the javascript is on their site and working without errors (i.e is there another script blocking ours).

Now the past couple of days, i have been trying to find similar cases on the web and the only thing i have been suggested, was Phantomjs however there are NO examples on how to even get close to what i want to achieve.

So my question to you:

  1. is it possible to check if a site has a certain javascript.
  2. is it possible to check if the javascript is running without errors(if the console throws errors or not)

I hope, that i wont get misunderstood this time :) if you have any questions, please just leave a message, and i will respond as fast as possible!

The phantomJs Solution (origianlly posted by Elias)

This is my code:

   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.marcrasmussen.com',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.apply(scripts, [function(elem)
        {//check all loaded scripts
              if (/jquery\.js/.js.js.test(elem.getAttribute('src')))
            {//this src attribute refers your script
                usesOurScript = true;//set to true
            }
        }]);
        return {page: location.href, found: usesOurScript};//return its href and the use-status
    });
    //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();
});

And there is no output it just keeps running forever when i run it from php:

Test.php

<?php echo shell_exec('phantomjs hello.js');

?>

回答1:


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.




回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/18329760/check-if-my-javascript-is-loaded-on-a-site

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!