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

如何在solr-node客户端应用中传递查询关键词与Apache Solr交互

解决方案:前端表单传参到Express后端,再查询Solr

你之前的核心问题是前端误用了Node.js专属的Solr库,而且跳过自己的后端直接连Solr——这既不符合浏览器环境的运行规则,也存在安全风险。正确的流程是:前端表单提交关键词到你的Express后端 → 后端用solr-node查询Solr → 后端把结果返回给前端展示。

以下是具体的代码修改步骤:


1. 修改Express后端代码(支持动态接收查询关键词)

调整/search接口,从URL参数中获取用户输入的关键词,替换原来的硬编码内容:

const express = require('express');
const bodyParser = require('body-parser');
const app = express();

app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended: true}));
app.use(express.static(__dirname + '/public'));

// Solr客户端初始化(保持原有配置)
const SolrNode = require('solr-node');
const client = new SolrNode({
  host:'localhost',
  port:'8983',
  core:'mycollection',
  protocol:'http'
});

// 支持动态查询的/search接口
app.get('/search', (req, res) => {
  // 从URL的?q=xxx参数中获取用户输入的关键词
  const userQuery = req.query.q;
  
  // 处理空查询的边界情况
  if (!userQuery) {
    return res.status(400).send('请输入搜索关键词');
  }

  // 动态构建Solr查询(用encodeURIComponent避免特殊字符破坏查询语法)
  const strNewQuery = client.query()
    .q(`text:${encodeURIComponent(userQuery)}`)
    .addParams({
      wt: 'json',
      indent: true
    });

  client.search(strNewQuery, (err, result) => {
    if (err) {
      console.error('Error querying Solr:', err);
      return res.status(500).send('查询Solr失败');
    }

    // 格式化结果(注意修正你之前的拼写错误:titile → title)
    const formattedResults = result.response.docs.map(doc => ({
      id: doc.id,
      title: doc.filename
    }));

    // 两种返回方式二选一:
    // 方式1:返回JSON给前端异步请求(适合无刷新搜索)
    res.json({ listTitle: "搜索结果", newListItems: formattedResults });
    // 方式2:渲染EJS页面(适合传统跳转式搜索)
    // res.render("list", {listTitle: "搜索结果", newListItems: formattedResults});
  });
});

app.get("/about", function(req, res) {
  res.render("about");
});

// 启动服务器
const port = 3030;
app.listen(port, ()=> {
  console.log('Solr-node server listening on port: ' + port);
});

2. 修改前端代码(通过请求后端接口实现搜索)

前端不需要引入任何Solr库,直接用原生fetch发送请求即可:

<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Solr搜索页面</title>
</head>
<body>
  <form id="searchForm">
      <input type="text" id="queryInput" placeholder="输入关键词搜索">
      <button type="submit">搜索</button>
  </form>
  <div id="results"></div>

  <script type="text/javascript">
    // 监听表单提交事件
    document.getElementById('searchForm').addEventListener('submit', async (e) => {
      e.preventDefault(); // 阻止表单默认跳转行为
      const query = document.getElementById('queryInput').value.trim();
      
      // 空输入校验
      if (!query) {
        alert('请输入搜索关键词');
        return;
      }

      try {
        // 发送请求到后端的/search接口,带上查询参数
        const response = await fetch(`/search?q=${encodeURIComponent(query)}`);
        if (!response.ok) {
          throw new Error(`请求失败:${response.status}`);
        }
        const data = await response.json();
        
        // 渲染搜索结果
        const resultsDiv = document.getElementById('results');
        resultsDiv.innerHTML = ''; // 清空之前的结果
        
        if (data.newListItems.length === 0) {
          resultsDiv.innerHTML = '<p>未找到匹配结果</p>';
          return;
        }

        data.newListItems.forEach(item => {
          resultsDiv.innerHTML += `<p>ID: ${item.id} | 文件名: ${item.title}</p>`;
        });
      } catch (error) {
          console.error('搜索出错:', error);
          alert('搜索失败,请稍后重试');
      }
    });
  </script>
</body>
</html>

可选:传统服务器端渲染方案

如果不想用异步请求,也可以直接让表单提交后跳转到后端渲染的EJS页面,只需修改前端表单代码:

<form action="/search" method="GET">
  <input type="text" name="q" placeholder="输入关键词搜索">
  <button type="submit">搜索</button>
</form>

同时后端保持res.render("list", ...)的逻辑即可,这种方式不需要前端的JS交互代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:14:50