zoukankan      html  css  js  c++  java
  • Vue实现前端标签绑定搜索

    前言

    • 在开发Metasploit前端时需要实现一个搜索payload的功能,由于是通过rpc服务获取当前exploit可用的payload,这是在内存里的元数据获取的数据,所以并没有像数据库这样有过滤功能,就有了使用前端实现标签搜索。

    实现思路

    • 首先把payload的全称按照/分词生成标签,例如:windows/meterpreter/reverse_tcp分割后变成windowsmeterpreterreverse_tcp三个标签,按照这种方法将所有的payload分成标签,然后去重。
    async compatible_payloads(fullname) {
      await module_compatible_payloads(fullname).then(response => {
        this.payloads_all = response.result.payloads
      })
    },
    
    • 先获取当前exploit可用payload,存放在payloads_all,然后监听payloads_all的变化,拷贝一份用于过滤操作,存放在payloads_filter,当payloads_filter变化时生成分词标签,将标签去重后存放在payloads_tags_all,当payloads_tags_all变化后再拷贝一份用于过滤操作,可能有点绕。
    watch: {
      // 拷贝一份用于过滤
      payloads_all: function() {
        this.payloads_filter = this.payloads_all
      },
      // 拷贝一份用于过滤
      payloads_tags_all: function() {
        this.payloads_tags_filter = this.payloads_tags_all
      },
      payloads_filter: function() {
        var tags = []
        this.payloads_filter.forEach(payload_line => {
          // 生成payload标签
          tags.push(...payload_line.split('/'))
        })
        this.payloads_tags_all = Array.from(new Set(tags))
      }
    },
    

    payload标签搜索

    • 在element的选择器中定义下面属性,远程方法为load_tags
    <el-select
      v-if="activeStep==1"
      v-model="payload.tags"
      default-first-option
      clearable
      multiple
      filterable
      remote
      style=" 350px"
      placeholder="tags"
      :remote-method="load_tags"
      :loading="tags_loading"
      @change="select_payload_tags"
    >
      <el-option
        v-for="(p,index) in payloads_tags_filter"
        :key="index"
        :label="p"
        :value="p"
      />
    </el-select>
    
    • 下面的是load_tags的方法,和一般过滤一样,没什么特别的,判断过滤的关键词不为空就过滤,关键词为空就将之前保存的payloads_tags_all覆盖掉payloads_tags_filter
    load_tags(query) {
      if (query !== '') {
        this.tags_loading = true
        this.payloads_tags_filter = this.payloads_tags_all.filter(p => {
          return p.toLowerCase().indexOf(query.toLowerCase()) > -1
        })
        this.tags_loading = false
      } else {
        this.payloads_tags_filter = this.payloads_tags_all
      }
    },
    
    • 这个方法最后改变了payloads_tags_filter,将payload标签可选范围缩小了。
    select_payload_tags() {
      this.load_payload('')
    },
    
    • 最后点击标签触发payload搜索load_payload方法。

    payload搜索

    • 在element的选择器中定义下面属性,远程方法为load_payload
    <el-select
      v-model="payload.fullname"
      default-first-option
      clearable
      filterable
      remote
      reserve-keyword
      style=" 350px"
      placeholder="fullname"
      :remote-method="load_payload"
      :loading="select_loading"
    >
      <el-option
        v-for="(p,index) in payloads_filter"
        :key="index"
        :label="p"
        :value="p"
      />
    </el-select>
    
    • 下面应该就是核心代码了
    load_payload(query) {
      // 搜索payload标签
      if (query !== '' || this.payload.tags.length) {
        this.select_loading = true
        this.payloads_filter = this.payloads_all.filter(p => {
          var is_include = (intersection(compact(p.split('/')), compact(this.payload.tags)).length === this.payload.tags.length)
          if (!is_include) {
            return false
          } else if (query !== '') {
            return p.toLowerCase().indexOf(query.toLowerCase()) > -1
          } else {
            return true
          }
        })
        this.select_loading = false
      } else {
        this.payloads_filter = this.payloads_all
      }
    },
    
    • 有两个地方触发了load_payload方法,第一个在payload搜索时触发,会传关键词搜索;第二个在选择标签后改变payload.tags数组后触发,会传一个空字符串搜索,先判断关键词是否为空,或者payload.tags数组的长度是否大于0,有一个为真就加锁进入过滤操作,下面讲一下搜索过滤的思路。

    搜索过滤

    • 因为我们payload.tags是一个数组集合,这不用每一个标签都去判断是否在payload的全称里,有一个非常简单的方法,先将payload的全称分割得到标签,再和payload.tags做集合求并集操作,得到并集后和payload.tags作比较,如果是一样就表明payload全称里有payload.tags里的标签,而且是准确的。
  • 相关阅读:

    链表
    队列
    稀疏数组
    SQL——流程控制
    SQL——存储过程与函数
    SOA
    MVC模式
    《一线架构师实践指南》--阅读笔记三
    《一线架构师实践指南》-阅读笔记二
  • 原文地址:https://www.cnblogs.com/Kali-Team/p/12957501.html
Copyright © 2011-2022 走看看