如何在Chrome扩展弹窗中展示Promise返回的Google搜索结果?
解决浏览器扩展弹窗展示Promise返回搜索结果的问题
嘿,我来帮你搞定这个浏览器扩展的需求!你想在弹窗里展示Promise返回的Google搜索前10条相似结果对吧?刚好我对这块挺熟的,给你捋捋思路和具体实现代码。
首先,核心问题是处理异步Promise的结果并渲染到弹窗DOM,因为Promise是异步执行的,不能直接同步获取值,得用async/await或者.then()来处理。下面是完整的实现步骤和代码:
1. 整体流程梳理
- 点击弹窗按钮时,提取当前页面的关键词
- 调用Google搜索API获取相似结果(返回Promise)
- 等待Promise resolve后,把结果渲染到弹窗的
#content元素里
2. 完整代码实现
const debiasButton = document.querySelector('#debias-me'); const debiasContent = document.querySelector('#content'); const apiKey = '你的Google API密钥'; // 替换成你自己的密钥 const searchEngineId = '你的自定义搜索引擎ID'; // Google Custom Search需要这个ID // 提取当前页面关键词的函数 function extractPageKeywords() { let keywords = []; // 优先从页面标题提取 const pageTitle = document.title.trim(); if (pageTitle) keywords.push(...pageTitle.split(/\s+/)); // 再从meta关键词标签提取 const metaKeywords = document.querySelector('meta[name="keywords"]'); if (metaKeywords) { keywords.push(...metaKeywords.content.split(',').map(k => k.trim())); } // 如果没有找到关键词,就从页面正文提取高频词(简单版逻辑) if (keywords.length === 0) { const pageText = document.body.innerText.replace(/\s+/g, ' ').trim(); const words = pageText.split(' ').slice(0, 100); // 过滤常见停用词(可以根据需求扩展这个列表) const stopWords = ['the', 'and', 'of', 'a', 'to', 'in', 'is', 'it', 'that', 'for']; keywords = [...new Set(words.filter(word => !stopWords.includes(word.toLowerCase())))]; } return keywords.join(' '); // 拼接成适合搜索的关键词字符串 } // 调用Google Custom Search API,返回搜索结果的Promise async function fetchSimilarSearchResults(keywords) { const searchUrl = `https://www.googleapis.com/customsearch/v1?q=${encodeURIComponent(keywords)}&num=10&key=${apiKey}&cx=${searchEngineId}`; try { const response = await fetch(searchUrl); if (!response.ok) throw new Error(`请求失败,状态码:${response.status}`); const searchData = await response.json(); return searchData.items || []; // 返回搜索结果数组,没有结果就返回空数组 } catch (error) { console.error('获取搜索结果出错:', error); return []; } } // 把搜索结果渲染到弹窗里的函数 function renderSearchResults(results) { debiasContent.innerHTML = ''; // 清空之前的内容 if (results.length === 0) { debiasContent.innerHTML = '<p>😅 没有找到相似的结果,试试刷新页面后再点击按钮吧!</p>'; return; } // 创建结果列表 const resultList = document.createElement('ul'); resultList.style.listStyle = 'none'; resultList.style.padding = '0'; resultList.style.margin = '0'; results.forEach(item => { const listItem = document.createElement('li'); listItem.style.marginBottom = '12px'; listItem.style.padding = '8px 12px'; listItem.style.borderRadius = '4px'; listItem.style.background = '#f8f9fa'; // 结果标题链接 const titleLink = document.createElement('a'); titleLink.href = item.link; titleLink.target = '_blank'; titleLink.style.color = '#1a0dab'; titleLink.style.fontWeight = 'bold'; titleLink.style.textDecoration = 'none'; titleLink.textContent = item.title; titleLink.addEventListener('mouseover', () => { titleLink.style.textDecoration = 'underline'; }); titleLink.addEventListener('mouseout', () => { titleLink.style.textDecoration = 'none'; }); // 结果摘要 const snippetPara = document.createElement('p'); snippetPara.style.margin = '4px 0 0 0'; snippetPara.style.fontSize = '14px'; snippetPara.style.color = '#545454'; snippetPara.textContent = item.snippet; listItem.appendChild(titleLink); listItem.appendChild(snippetPara); resultList.appendChild(listItem); }); debiasContent.appendChild(resultList); } // 绑定按钮点击事件 debiasButton.addEventListener('click', async () => { // 显示加载状态 debiasContent.innerHTML = '<p>🔍 正在搜索相似结果,请稍候...</p>'; // 提取关键词 const pageKeywords = extractPageKeywords(); // 等待搜索结果返回 const similarResults = await fetchSimilarSearchResults(pageKeywords); // 渲染结果 renderSearchResults(similarResults); });
3. 几个关键注意事项
- API配置:你需要先在Google Cloud Console启用「Custom Search API」,并创建自定义搜索引擎获取
searchEngineId,同时确保你的API密钥有足够的配额。 - CORS问题:如果直接在弹窗脚本里调用API遇到跨域错误,建议把API请求移到扩展的
background.js中,然后通过chrome.runtime.sendMessage和弹窗脚本通信,这样可以绕过浏览器的CORS限制。 - 关键词优化:上面的关键词提取是基础版,你可以根据需求升级,比如引入NLP库提取更精准的关键词,或者让用户手动输入补充关键词。
- 样式定制:代码里加了一些内联样式,你也可以把样式写到扩展的CSS文件里,让弹窗更美观。
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

