You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Kibana插件中获取Elasticsearch数据的最优方案咨询

嘿,刚好我之前在开发Kibana React插件时也遇到过类似的需求,给你梳理下最优的实现方案,绝对能解决你遇到的跨域和安全问题:

最优方案:复用Kibana内置的Elasticsearch客户端

这是最推荐的方案,原因很简单:Kibana本身已经和Elasticsearch建立了稳定的连接,并且处理了认证、权限、请求转发等核心问题,你的插件直接复用这个连接即可,完全不用操心跨域,还能继承Kibana的安全体系。

具体实现步骤

  1. 在插件启动阶段获取ES客户端
    在Kibana插件的plugin.ts文件中,你可以通过core.elasticsearch.client拿到已经配置好的客户端实例,然后把它传递给你的React应用:

    export class MySearchPlugin implements Plugin<MyPluginSetup, MyPluginStart> {
      public setup(core: CoreSetup) {
        // 获取以当前用户身份发起请求的ES客户端
        const esClient = core.elasticsearch.client.asCurrentUser;
    
        // 注册插件应用,将ES客户端传入React组件
        core.application.register({
          id: 'my-search-plugin',
          title: '自定义搜索插件',
          async mount(params: AppMountParameters) {
            const [coreStart] = await core.getStartServices();
            const { renderSearchApp } = await import('./application');
            // 把客户端传给React应用
            return renderSearchApp(coreStart, params, esClient);
          },
        });
      }
    
      public start(core: CoreStart) {}
    }
    
  2. 在React组件中使用客户端执行搜索
    拿到客户端实例后,就可以直接调用Elasticsearch的搜索API了,完全不用处理跨域:

    import React, { useState } from 'react';
    
    export const SearchComponent = ({ esClient }) => {
      const [searchQuery, setSearchQuery] = useState('');
      const [searchResults, setSearchResults] = useState([]);
    
      const handleSearch = async () => {
        if (!searchQuery.trim()) return;
        
        try {
          const response = await esClient.search({
            index: '你的索引名称', // 或者Kibana索引模式ID
            body: {
              query: {
                match: {
                  content: searchQuery // 替换成你要搜索的字段
                }
              }
            }
          });
          // 提取搜索结果
          setSearchResults(response.hits.hits.map(hit => hit._source));
        } catch (error) {
          console.error('搜索失败:', error);
        }
      };
    
      return (
        <div className="search-plugin-container">
          <input
            type="text"
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            placeholder="输入搜索关键词..."
          />
          <button onClick={handleSearch}>搜索</button>
          <div className="results">
            {searchResults.length > 0 ? (
              <ul>
                {searchResults.map((item, idx) => (
                  <li key={idx}>{JSON.stringify(item)}</li>
                ))}
              </ul>
            ) : (
              <p>暂无结果</p>
            )}
          </div>
        </div>
      );
    };
    
关于elasticsearch.js的正确用法

你提到的elasticsearch.js其实Kibana已经内置了,不需要单独安装,但绝对不要自己创建新的Client实例直接连接ES——那样会回到跨域的问题,而且还要手动处理认证、权限等复杂逻辑。正确的用法就是上面提到的,直接复用Kibana提供的core.elasticsearch.client,它本质上就是基于elasticsearch.js封装好的实例。

为什么不推荐直接从浏览器调用Elastic API

你之前遇到的跨域问题是浏览器同源策略导致的,而修改ES配置允许跨域确实有很大安全隐患:

  • 这会允许任意域名向ES发送请求,可能导致未授权的数据访问或恶意操作
  • 绕过了Kibana的权限控制体系,用户的身份认证无法传递到ES请求中

额外进阶:使用Kibana Data服务的Search API

如果你需要更贴合Kibana生态的搜索能力(比如支持索引模式、时间过滤、可视化兼容等),可以使用Kibana的data.search服务,它封装了更适合Kibana场景的搜索逻辑:

const searchResponse = await coreStart.data.search.search({
  params: {
    index: '你的索引模式ID',
    body: {
      query: { match: { content: searchQuery } },
      // 还可以加入时间范围过滤等Kibana常用参数
    }
  }
});

总的来说,复用Kibana内置的ES客户端或data.search服务是最稳妥、最符合Kibana插件开发规范的方案,既解决了跨域问题,又保证了安全性,开发起来也更高效。

内容的提问来源于stack exchange,提问作者AloysiusParedes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 07:08:45