6

我想知道是否有办法检查是否从浏览器的控制台或源代码调用了 javascript 函数。

我定义了一个可以检查它是来自控制台还是来自页面的函数,但它只适用于谷歌浏览器,它不适用于 Firefox,我没有测试其他浏览器

function fromConsole()
{
    var Caller = arguments.callee.caller;
    while(Caller.caller != null)
        Caller = Caller.caller;
    return (Caller.toString().indexOf("function (expression, objectGroup,"))!=-1;
}

此功能如何工作

这个函数查找调用我们函数的顶部函数。在谷歌浏览器中,如果从控制台调用顶部函数的定义function (expression, objectGroup,在Firefox中包含此字符串,则没有函数

让我给你详细解释一下

假设我们有这个例子

function a()
{
    b();
}
function b()
{
    return c();
}
function c()
{
    console.log(fromConsole());
}

如果我们从页面调用函数 a() ,它在控制台中显示为 false (因为顶部函数是 a() )但是,如果我们从控制台调用它,它显示为 true,因为顶部函数是 this " function (expression, objectGroup,..."

在 Firefox 中,无论您是从控制台还是从您的页面调用函数,顶级函数始终是 a()

我的问题是:有没有办法知道函数是否从控制台调用?

4

3 回答 3

12

在 Chrome 中,控制台总是调用中间 JavaScript 函数,在 Firefox 中,调用直接来自本机代码。因此,您可以arguments.callee.caller在 Chrome 中进行检查,但在 Firefox 中它始终是null. Safari 在这里的行为与 Firefox 相同,因此检查调用者确实是一种仅适用于 Chrome 的技巧。

不过,您可以检查的是Error.stackproperty。以下功能适用于 Firefox、Chrome 甚至 Safari:

function fromConsole()
{
    var stack;
    try
    {
       // Throwing the error for Safari's sake, in Chrome and Firefox
       // var stack = new Error().stack; is sufficient.
       throw new Error();
    }
    catch (e)
    {
        stack = e.stack;
    }
    if (!stack)
        return false;

    var lines = stack.split("\n");
    for (var i = 0; i < lines.length; i++)
    {
        if (lines[i].indexOf("at Object.InjectedScript.") >= 0)
            return true;   // Chrome console
        if (lines[i].indexOf("@debugger eval code") == 0)
            return true;   // Firefox console
        if (lines[i].indexOf("_evaluateOn") == 0)
            return true;   // Safari console
    }
    return false;
}

这将向上遍历堆栈,直到找到与控制台对应的条目。这意味着fromConsole()不需要直接调用,中间可以有任意数量的其他函数调用。尽管如此,它还是很容易被欺骗,例如使用setTimeout()

setTimeout(fromConsole, 0);

这里调用者将是本机超时处理程序,不再指向控制台。

于 2014-07-28T07:30:31.697 回答
4

这是查看它是从公共(全局,由 js 控制台调用)还是私有(您的代码)上下文调用的跨浏览器方式:

(function() { 
    window.f = function() {
        console.log('public')
    } ;
    //f will be this function in the rest of the code in this outer function:
    var f = function() {
        console.log('private'); 
    }
    f();
    //more code here...

}) ()

外部函数中的代码将使用私有函数,而f()从控制台运行将运行公共函数。

于 2014-07-29T01:41:05.897 回答
3

对于 Chrome,您只需检查该keys功能是否可用。它是 chrome命令行 API的一部分,仅在从控制台执行代码时可用

function myFunction() {
  var fromConsole = typeof keys === 'function' && keys.toString().indexOf('Command Line API') !== -1
  if (fromConsole) {
    alert('From console')
  } else {
    alert('Not from console')
  }
}
于 2018-03-18T21:28:44.057 回答