如何在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
相关产品推荐
相关产品推荐

