1

我以前问过这个问题,但似乎我被误解了,因此我决定再问一次,但这次有很多信息:

对于懒惰的读者,我的目标是:

有没有办法通过 PHP 或 Ajax 检查是否在外部站点上启用了 javascript

详细说明:

好的,所以我的公司有很多客户,当这些客户在我们的网站上注册时,他们会收到一个javascript. 然后他们可以script在自己的网站上使用它来获得一些额外的功能。

现在,客户拥有的所有网站都存储在我们的 CMS 系统中(就像他们拥有与我们签署的所有网站的列表一样)。

现在我的老板给了我以下任务:

我们需要一个功能,以便用户可以按下“测试”按钮,系统将测试 javascript 是否在他们的网站上并且正常工作(即是否有另一个脚本阻止我们的)。

现在在过去的几天里,我一直在尝试在 Phantomjs 上找到类似的案例,web我唯一得到的建议是 Phantomjs,但是没有关于如何接近我想要实现的目标的示例。

所以我的问题是:

  1. 是否可以检查网站是否有特定的 javascript。
  2. 是否可以检查 javascript 是否在没有错误的情况下运行(如果控制台抛出错误)

希望这次不会被误会:)如果您有任何问题,请留言,我会尽快回复!

phantomJs 解决方案(最初由 Elias 发布)

这是我的代码:

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

当我从 php 运行它时,它没有任何输出,它只会一直运行:

测试.php

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

?>
4

3 回答 3

3

我也会在这里发。由于我是让您使用 phantomjs 的人,因此我认为为您提供问题的答案是公平的。
以下脚本在无头幻影浏览器中打开一个页面,记录该页面在实际浏览器中产生的任何控制台消息,(使用onConsoleMessage事件),如果页面无法加载,它还会记录错误,并且,如果页面打开时没有问题,它会检查<script>该页面上的所有标签,寻找您的 javascript 文件。

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

如果该文件执行 jQ 之类的操作(创建对某个对象的全局引用),您甚至可以将其添加到page.evaluate回调中:

    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

注意:
此代码未经测试,我只是在脑海中写下它。它可能包含愚蠢的错字。这不是对你所有祈祷的复制粘贴答案。
我相信page.evaluate回调能够返回一些东西,但是:它在加载页面的上下文中运行,并且是沙盒的,所以你可能不得不强制出错:

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

通过抛出这个没有被捕获的自定义错误,它最终会出现在控制台中,你可以强制page.onConsoleMessage处理程序处理这个异常。在某种程度上,如果它们导致发生无限循环问题,那可能是一种绕过沙盒限制的方法。

于 2013-08-20T08:36:22.410 回答
1

是否可以检查网站是否有特定的 JavaScript?

你可以做两件事,我认为使用 JavaScript 的那件事更容易实现。

使用 PHP:

  • 从数据库中的 URL 获取内容
  • 将其加载到DOMDocument并搜索代码的特定部分
  • 从该文档中提取所有外部 JavaScript 文件
    • 也获取它们并在其中搜索特定的代码部分

使用 JavaScript

  • 在构造函数或启动方法中实现 AJAX 请求
  • 发送执行脚本的当前域并将其与数据库中的列表进行比较

自托管

  • 正如在编写此答案时所讨论的,这是另一种可能性,因为您的日志可以显示此脚本访问的所有页面

是否可以检查 javascript 是否在没有错误的情况下运行?

这个有点复杂,因为你在运行时检查过这个。想象一下,您的脚本的用户扩展或修改了您的代码,或者只是以错误的方式使用它,或者与您的代码有冲突。也许这个代码永远不会到达,因为它调用了一些可能会或可能不会触发的用户交互。

一种可能性是在发生错误时向您发送 AJAX 请求。window.onerror您可以为此目的签出:

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

这将为您提供一些详细信息,您可以使用 AJAX 请求将这些信息传递给您的服务器。

于 2013-08-20T08:28:08.720 回答
0

一个环形交叉路口或更简单的方法是创建一个具有唯一名称的虚拟对象定义,例如“your_company_name_”+some_hash。像 abc_45xcd。

//your custom js file

//BEWARE! this is global namespace. 

function abc_45xcd(){
      console.log('abc_45scd custom js is loaded');
}

当您单击测试按钮时,您可以尝试创建一个新对象

   var x = new abc_45scd();

您可以检查构造函数和类型以检查它是否是您自己的自定义虚拟对象。

注意:这实际上是一个幼稚的解决方案,因为有些人可能会在他们的脚本中创建一个同名的对象。此外,它无缘无故地污染了全局命名空间。

于 2013-08-20T08:07:14.147 回答