简体   繁体   English

Javascript-如何安全地评估表达式以实现自动完成?

[英]Javascript - how to safely evaluate expressions for auto-complete?

I'm adding an auto-complete feature to my javascript console (the script is running on a remote browser). 我正在向JavaScript控制台添加自动完成功能(脚本正在远程浏览器上运行)。

My approach is to evaluate the expression where the caret is, and if the evaluation yield an object - suggest it's list of properties for auto-complete. 我的方法是在插入符所在的位置评估表达式,如果评估产生了object ,则建议使用自动完成属性列表。 For instance (where | is the caret position): 例如(其中|是插入符号的位置):

document.|

in this case I evaluate var evalExp = document; 在这种情况下,我评估var evalExp = document; then iterate it's members for (var prop in evalExp) to create a list of auto-complete suggestions. 然后迭代它的成员for (var prop in evalExp)以创建自动完成建议的列表。

The problem is, if the expression I'm evaluating contains functions or assignments, such as: 问题是,如果我正在评估的表达式包含函数或赋值,例如:
count++ , count++
e.click() or e.click()
alert('Some message') , alert('Some message')
I wouldn't want it to be executed, since it changes the browsers state instead of just evaluating and returnning an object. 我不希望它被执行,因为它改变了浏览器的状态,而不仅仅是评估并返回一个对象。

Therefore, I want to avoid evaluating any expressions if they call functions, or if they contain assignment operators. 因此,如果它们调用函数或它们包含赋值运算符,我想避免对任何表达式求值。

Questions: 问题:

  • Are there any other kinds of expressions I should avoid evaluating? 我还应该避免评估其他表达式吗?
  • What alternative ways are there to create the suggestion list? 有什么其他方法可以创建建议列表?

  • One alternative way to create the suggestion list is to get the object model as a string, split by periods, and loop over the last object's properties. 创建建议列表的另一种方法是将对象模型作为字符串获取,按句点分隔,并遍历最后一个对象的属性。 For example... 例如...

    var line = "document.body.getElementsBy",
    objs = line.replace(/[\(\{\[]+.*?[\)\}\]]+/g, '').split(/[^\w\-]/),
    lastObj = objs[objs.length - 1],
    currentObj = window,
    i = 0;
    
    if (objs[0] === 'window') {
        objs.splice(0, 1);
    }
    
    objs.splice(-1, 1);
    
    while (currentObj.hasOwnProperty(objs[i])) {
        currentObj = currentObj[objs[i++]];
    }
    
    for (var prop in currentObj) {
        if (prop.indexOf(lastObj) === 0) {
            console.log('Auto complete:', lastObj, 'with', prop);
        }
    }
    
    /* Outputs:
    Auto complete: getElementsBy with getElementsByTagName
    Auto complete: getElementsBy with getElementsByTagNameNS
    Auto complete: getElementsBy with getElementsByClassName
    */
    

    Your final code will be more complex but that's the general idea. 您的最终代码将更加复杂,但这是基本思想。

    声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM