如何用单Fetch请求实现书籍多条件搜索(作者/标题/出版日期)
解决方案
后端统一路由实现(Express示例)
核心思路是创建单一搜索路由,根据请求中的查询参数类型调用对应SQL查询函数,解决你之前if分支提前终止的问题,可选择单条件匹配或多维度模糊搜索两种方案。
方案1:单条件匹配(按参数类型区分)
// 导入已实现的查询函数 const { getBooksByAuthor, getBooksByTitle, getBooksByDate, getAllBooks } = require('./your-query-module'); // 统一搜索路由 app.get('/api/books/search', async (req, res) => { const { author, title, publishDate } = req.query; let books = []; try { // 按参数存在性匹配对应查询函数 if (author) { books = await getBooksByAuthor(author); } else if (title) { books = await getBooksByTitle(title); } else if (publishDate) { books = await getBooksByDate(publishDate); } else { // 无参数时返回全部书籍(可根据需求改为返回错误提示) books = await getAllBooks(); } res.json({ success: true, data: books }); } catch (error) { console.error('搜索出错:', error); res.status(500).json({ success: false, error: '服务器内部错误' }); } });
方案2:模糊搜索(自动匹配多维度)
如果希望用户无需选择搜索类型,输入关键词即可自动匹配作者、标题或出版日期:
app.get('/api/books/search', async (req, res) => { const { keyword } = req.query; let mergedBooks = []; try { if (!keyword) { return res.status(400).json({ error: '请输入搜索关键词' }); } // 并行查询作者和标题匹配结果 const [authorMatches, titleMatches] = await Promise.all([ getBooksByAuthor(keyword), getBooksByTitle(keyword) ]); // 合并结果并按书籍ID去重 mergedBooks = [...new Map([...authorMatches, ...titleMatches].map(book => [book.id, book])).values()]; // 判断关键词是否为日期格式,匹配出版日期 const isDateFormat = /^\d{4}-\d{2}-\d{2}$/.test(keyword); if (isDateFormat) { const dateMatches = await getBooksByDate(keyword); dateMatches.forEach(book => { if (!mergedBooks.find(b => b.id === book.id)) { mergedBooks.push(book); } }); } res.json({ success: true, data: mergedBooks }); } catch (error) { console.error('搜索出错:', error); res.status(500).json({ success: false, error: '服务器内部错误' }); } });
前端单Fetch请求实现
根据后端方案,前端只需构造对应查询参数,发起一次fetch请求即可。
对应方案1的前端代码(带搜索类型选择)
<div class="search-bar"> <input type="text" id="searchContent" placeholder="输入搜索内容"> <select id="searchType"> <option value="author">作者</option> <option value="title">书籍标题</option> <option value="publishDate">出版日期</option> </select> <button onclick="handleSearch()">搜索</button> </div> <div id="bookResults"></div>
async function handleSearch() { const content = document.getElementById('searchContent').value.trim(); const type = document.getElementById('searchType').value; if (!content) { alert('请输入搜索内容'); return; } try { // 构造查询参数 const params = new URLSearchParams(); params.append(type, content); const response = await fetch(`/api/books/search?${params}`); const result = await response.json(); renderResults(result.data); } catch (err) { console.error('请求失败:', err); alert('搜索失败,请稍后重试'); } } function renderResults(books) { const container = document.getElementById('bookResults'); container.innerHTML = ''; if (books.length === 0) { container.innerHTML = '<p>未找到匹配的书籍</p>'; return; } books.forEach(book => { const bookCard = document.createElement('div'); bookCard.className = 'book-card'; bookCard.innerHTML = ` <h3>${book.title}</h3> <p>作者:${book.author}</p> <p>出版日期:${book.publishDate}</p> `; container.appendChild(bookCard); }); }
对应方案2的前端代码(模糊搜索)
<div class="search-bar"> <input type="text" id="searchKeyword" placeholder="输入作者、标题或出版日期"> <button onclick="handleFuzzySearch()">搜索</button> </div> <div id="bookResults"></div>
async function handleFuzzySearch() { const keyword = document.getElementById('searchKeyword').value.trim(); if (!keyword) { alert('请输入搜索关键词'); return; } try { const response = await fetch(`/api/books/search?keyword=${encodeURIComponent(keyword)}`); const result = await response.json(); renderResults(result.data); } catch (err) { console.error('请求失败:', err); alert('搜索失败,请稍后重试'); } } // renderResults函数同上
内容的提问来源于stack exchange,提问作者Eugene
相关产品推荐
相关产品推荐

