我们怎么知道一个函数是从控制台还是从源代码中调用 [英] How can we know if a function is called from console or from source code

查看:153
本文介绍了我们怎么知道一个函数是从控制台还是从源代码中调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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



这个函数如何工作



这个函数寻找称为函数的顶层函数。如果从控制台调用它的顶部函数包含此字符串函数(表达式,objectGroup,在Firefox中,没有功能

我们有这个例子

 








$ b $







$ b $ p>

如果我们从页面调用函数a(),它会在控制台中显示false(因为顶层函数是一个()),但是如果我们从控制台调用它显示为true,因为顶层函数是这个函数(expression,objectGroup,...



在firefox中,最上面的函数总是一个()你从控制台或者从你的页面调用你的函数

我的问题是:有没有一种方法,我们可以知道,如果该函数是从控制台调用或不是?

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



然而,您可以检查的是 Error.stack 属性。以下功能适用于Firefox,Chrome甚至是Safari:

$ $ $ $ $ $ $ $ $ $ $ $ $栈;
try
{
//在Safari和Firefox浏览器中抛出错误
// var stack = new Error()。stack;足够了。
抛出新的Error();
}
catch(e)
{
stack = e.stack;

if(!stack)
return false;

var lines = stack.split(\\\
);
for(var i = 0; i< lines.length; i ++)
{
if(lines [i] .indexOf(at Object.InjectedScript。)> = 0 )
返回true; // Chrome console
if(lines [i] .indexOf(@ debugger eval code)== 0)
return true; // Firefox控制台
if(lines [i] .indexOf(_ evaluateOn)== 0)
return true; // Safari控制台
}
返回false;



$ b $ p
$ b

这将直到堆栈找到与控制台相对应的条目。这意味着来自Console()的不需要直接调用,其间可以有任意数量的其他函数调用。尽管如此,它很容易被欺骗,例如通过使用 setTimeout()

  setTimeout(fromConsole,0); 

这里调用者将是本地超时处理程序,没有任何指向控制台的地方。 >

I want to know if there is a way to check if a javascript function is being called from console of the browser or from source code.

I defined a function that can check if it's from console or from the page but it works only in google chrome, it doesn't work in firefox, I didn't test other browsers

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

How this function works

this function looks for the top function that called our function. in google chrome the definition of the top function if its being called from console contains this string function (expression, objectGroup, in firefox, there is no function

Let me explain to you in details

let's say we have this example

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

If we call the function a() from the page , it shows in the console false (because the top function is a() ) however, if we call it from console it shows true, because the top function is this "function (expression, objectGroup,..."

In firefox, the top function is always a() wether you call your function from console or from your page

My question is : is there a way we can know if the function is called from console or not ?

解决方案

In Chrome the console always calls intermediate JavaScript functions, in Firefox the call comes directly from native code. As a consequence, you can inspect arguments.callee.caller in Chrome but in Firefox it will always be null. Safari behaves the same as Firefox here, so inspecting the caller is really a trick that only works in Chrome.

What you can check nevertheless is Error.stack property. The following function works in Firefox, Chrome and even 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;
}

This will walk up the stack until it finds an entry corresponding to the console. This means that fromConsole() doesn't need to be called directly, there can be any number of other function calls in between. Still, it can easily be tricked, e.g. by using setTimeout():

setTimeout(fromConsole, 0);

Here the caller will be the native timeout handler, nothing pointing to the console any more.

这篇关于我们怎么知道一个函数是从控制台还是从源代码中调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆