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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:32:14