Chrome扩展执行node popup.js时出现ReferenceError: document is not defined
错误分析与修复方案
核心错误原因
- 环境不兼容:
document是浏览器DOM API专属对象,Node.js是服务器端运行环境,根本没有这个对象,直接用node popup.js执行浏览器端代码必然报错。 - 架构逻辑错误:Chrome扩展Manifest V3中,popup属于浏览器上下文,不能直接引入Node.js的
mysql模块(浏览器不支持Node.js的require语法和原生Node模块);同时你把database.js设为service worker也是错误的,service worker同样是浏览器环境,无法运行Node.js的数据库代码。
具体修复步骤
1. 停止错误的执行方式
不要再用node popup.js运行popup代码,Chrome扩展的代码必须通过Chrome浏览器加载扩展来运行,而非Node.js终端。
2. 重构数据库访问逻辑
浏览器环境无法直接连接MySQL,必须通过后端接口中转数据。你需要搭建一个简单的Node.js后端服务,处理数据库操作,然后在扩展中通过HTTP请求调用这个接口。
新建后端服务文件server.js
const express = require('express'); const mysql = require('mysql'); const cors = require('cors'); const app = express(); // 配置跨域和JSON解析 app.use(cors()); app.use(express.json()); // 数据库连接配置 const db = mysql.createConnection({ host: 'localhost', user: 'root', password: '', database: 'ARQ' }); // 连接数据库 db.connect((err) => { if (err) throw err; console.log('数据库连接成功'); }); // 处理添加人员的POST请求 app.post('/add-person', (req, res) => { const { name, age, nationality, description } = req.body; const sql = "INSERT INTO people (name, age, nationality, description) VALUES (?, ?, ?, ?)"; db.query(sql, [name, age, nationality, description], (err, result) => { if (err) { res.status(500).send('数据库操作失败'); return; } res.send('人员信息已成功添加'); }); }); // 启动服务 app.listen(3000, () => { console.log('后端服务运行在 http://localhost:3000'); });
3. 修改popup.js(适配浏览器环境)
移除Node.js的require调用,改用fetch API调用后端接口:
const submitBtn = document.querySelector("#submit"); submitBtn.addEventListener("click", async () => { // 获取表单输入值 const name = document.querySelector("#name").value.trim(); const age = document.querySelector("#age").value.trim(); const nationality = document.querySelector("#nationality").value.trim(); const description = document.querySelector("#description").value.trim(); // 简单校验输入 if (!name || !age || !nationality) { alert('请填写必填字段'); return; } try { // 调用后端接口提交数据 const response = await fetch('http://localhost:3000/add-person', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name, age, nationality, description }) }); const message = await response.text(); console.log(message); alert(message); // 清空表单 document.querySelector("#name").value = ''; document.querySelector("#age").value = ''; document.querySelector("#nationality").value = ''; document.querySelector("#description").value = ''; } catch (error) { console.error('提交失败:', error); alert('提交失败,请检查后端服务是否运行'); } });
4. 修正manifest.json配置
- 移除错误的
content_scripts(popup.js不需要注入到所有网页) - 移除
background中的database.js配置(service worker无法运行Node.js代码) - 添加
host_permissions,允许扩展访问本地后端服务
修正后的manifest.json:
{ "name": "ARQ Database", "version": "0.01", "description": "An easy way to find the best fit for the job.", "manifest_version": 3, "action": { "default_title": "Database Popup", "default_popup": "popup.html" }, "host_permissions": [ "http://localhost:3000/*" ] }
5. 正确运行流程
- 安装后端依赖:在终端执行
npm install express mysql cors - 启动后端服务:
node server.js - 加载Chrome扩展:打开Chrome扩展管理页面(地址栏输入
chrome://extensions/),开启开发者模式,点击“加载已解压的扩展程序”,选择你的扩展文件目录 - 测试功能:点击扩展图标,填写表单并提交
关键注意事项
- Chrome扩展的所有前端代码(popup、content script、service worker)都运行在浏览器沙箱环境,无法直接使用Node.js的核心模块或第三方Node包。
- 浏览器与数据库的交互必须通过后端接口中转,这是浏览器的同源策略和安全机制限制。
内容的提问来源于stack exchange,提问作者Lewan Paalvast
相关产品推荐
相关产品推荐

