Javascript 我们如何知道函数是从控制台调用的还是从源代码调用的

Javascript 我们如何知道函数是从控制台调用的还是从源代码调用的,javascript,google-chrome,firefox,google-chrome-devtools,firefox-developer-tools,Javascript,Google Chrome,Firefox,Google Chrome Devtools,Firefox Developer Tools,我想知道是否有一种方法可以检查是否从浏览器控制台或源代码调用javascript函数 我定义了一个功能,可以检查它是从控制台还是从页面,但它只在谷歌浏览器中工作,在firefox中不工作,我没有测试其他浏览器 function fromConsole() { var Caller = arguments.callee.caller; while(Caller.caller != null) Caller = Caller.caller; return (C

我想知道是否有一种方法可以检查是否从浏览器控制台或源代码调用javascript函数

我定义了一个功能,可以检查它是从控制台还是从页面,但它只在谷歌浏览器中工作,在firefox中不工作,我没有测试其他浏览器

function fromConsole()
{
    var Caller = arguments.callee.caller;
    while(Caller.caller != null)
        Caller = Caller.caller;
    return (Caller.toString().indexOf("function (expression, objectGroup,"))!=-1;
}
这个函数是如何工作的 此函数查找调用我们函数的顶级函数。在google chrome中,如果从控制台调用top函数,则其定义包含以下字符串
函数(expression,objectGroup,
),在firefox中,没有函数

让我给你详细解释一下

假设我们有这个例子

function a()
{
    b();
}
function b()
{
    return c();
}
function c()
{
    console.log(fromConsole());
}
如果我们从页面调用函数a(),它在控制台中显示为false(因为顶级函数是a()),但是如果我们从控制台调用它,它显示为true,因为顶级函数是这个“
函数(表达式,对象组,

在firefox中,无论是从控制台调用函数还是从页面调用函数,顶部函数始终是()


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

在Chrome中,控制台总是调用中间JavaScript函数,在Firefox中,调用直接来自本机代码。因此,您可以在Chrome中检查
参数。被调用方。调用方
,但在Firefox中,它将ys be
null
。Safari在这里的行为与Firefox相同,因此检查调用者实际上是一个仅在Chrome中有效的技巧

不过,您可以检查一下。以下功能在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;
}

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

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


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

对于Chrome,您只需检查
函数是否可用。它是Chrome的一部分,仅在从控制台执行代码时可用

function myFunction() {
  var fromConsole = typeof keys === 'function' && keys.toString().indexOf('Command Line API') !== -1
  if (fromConsole) {
    alert('From console')
  } else {
    alert('Not from console')
  }
}

我认为“console.error('helloworld')”也许可以帮助你。它会像这样在浏览器上回溯:在firefox中它不会回溯。我需要一个函数,而不是我可以手动完成的。你想解决什么问题?如果你想做某种反作弊,Chrome允许用户在适当的位置编辑JavaScript,从而可以在代码中添加函数调用。Th还有一些代理服务器也可以在传输过程中更改脚本。我不明白的是,如果在
setTimeout
中调用它并在中返回false,那么为什么
fromConsole
返回
true
(在Firefox中)chrome@Khalid:
setTimeout(函数(){console.log(fromConsole())},0)
在Firefox中仍将返回
true
,因为调用方是
function(){console.log(fromConsole())}
-这是由控制台创建的匿名函数,它在堆栈上也显示为
@debugger eval code
。但正如我所说,在
设置超时(fromConsole,0)
在Firefox中,它也会给你
false
。这是否意味着在所有情况下都不可能找到它???@Khalid:这就是我在回答中所说的。如果你运行
setTimeout(从控制台,0)
从控制台调用,那么代码的调用方不再是控制台-
setTimeout
是。如果有人通过控制台创建了一个
标记,例如,同样的情况会发生-该脚本可以调用您的函数,而不再是控制台调用它。您只有机会识别来自con的直接调用设置传递给被调用函数的事件参数,然后查找调用事件的目标…
event.target
我喜欢这种方法,尤其是当每个浏览器都有自己的控制台定义函数时。
(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...

}) ()
function myFunction() {
  var fromConsole = typeof keys === 'function' && keys.toString().indexOf('Command Line API') !== -1
  if (fromConsole) {
    alert('From console')
  } else {
    alert('Not from console')
  }
}