无需运行服务器,用JavaScript在HTML页面展示数据库信息及排障
问题:本地数据库数据如何无需服务器直接在HTML中渲染?
问题背景
我在FreeCodeCamp的JavaScript OOP课程第13步学会了把script.js里数组的对象值做成盒子展示。现在想换成自己数据库的数据,用Node.js把数据库连到script.js,也把表数据转成了对象列表,但没法关联HTML元素渲染——Node.js不能操作浏览器的document对象,运行时抛出以下错误:
c:\Users\Nicolás\Desktop\Gatoprojecto\script.js:2 const gatoCajas=document.getElementById("gatoContainer") ^ ReferenceError: document is not defined at Object.<anonymous> (c:\Users\Nicolás\Desktop\Gatoprojecto\script.js:2:17) at Module._compile (node:internal/modules/cjs/loader:1218:14) at Module._extensions..js (node:internal/modules/cjs/loader:1272:10) at Module.load (node:internal/modules/cjs/loader:1081:32) at Module._load (node:internal/modules/cjs/loader:922:12) at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12) at node:internal/main/run_main_module:23:47 Node.js v18.13.0
我试过Python、Django、Flask及Express.js等方案,但都需要运行HTTP服务器。想问有没有无需运行服务器、直接打开index.html就能实现的方法?
以下是我尝试的代码:
数据库连接代码(Node.js环境)
var con = mysql.createConnection({ host: "localhost", user: "root", password: "", database: "gatobase" }); con.connect(function (err) { if (err) throw err; console.log("Connected!"); con.query("select Color,edad,raza,peso from gatos_sin_adoptar", function (err,result,fields){ if (err) throw err; gatos = result; }) });
渲染代码(原本想直接操作DOM)
gatos.forEach( ({ color, edad, raza, peso }) => { gatoCajas.innerHTML += ` <div class="gato_caja"> <p class="gatoColor">Color: ${color}</p> <p class="gatoEdad">Edad: ${edad}</p> <p class="gatoRaza">Raza: ${raza}</p> <p class="gatoPeso">Peso: ${peso} Kg</p> </div> `; } );
可行解决方案(无需HTTP服务器)
方案1:预生成静态JSON文件
这是最直接的方案,把数据库数据导出成静态JSON文件,前端直接读取这个文件渲染:
- 写数据导出脚本:新建一个单独的Node.js文件(比如
export-db.js),专门负责从数据库读取数据并生成JSON文件:
const mysql = require('mysql'); const fs = require('fs'); const con = mysql.createConnection({ host: "localhost", user: "root", password: "", database: "gatobase" }); con.connect(err => { if (err) throw err; con.query("SELECT Color, edad, raza, peso FROM gatos_sin_adoptar", (err, result) => { if (err) throw err; // 将查询结果转为JSON并写入本地文件 fs.writeFileSync('./gatos-data.json', JSON.stringify(result)); console.log('数据已导出到gatos-data.json'); con.end(); // 关闭数据库连接 }); });
生成JSON文件:在终端运行这个脚本:
node export-db.js,成功后会在项目根目录生成gatos-data.json。前端读取JSON并渲染:修改前端的script.js(注意这个脚本是在浏览器环境运行,不是Node.js):
// 前端script.js,放在index.html的<script>标签里 const gatoCajas = document.getElementById("gatoContainer"); // 读取本地JSON文件 fetch('./gatos-data.json') .then(response => response.json()) .then(gatos => { // 注意:SQL查询返回的字段是Color(大写C),要和这里的变量名一致 gatos.forEach(({ Color, edad, raza, peso }) => { gatoCajas.innerHTML += ` <div class="gato_caja"> <p class="gatoColor">Color: ${Color}</p> <p class="gatoEdad">Edad: ${edad}</p> <p class="gatoRaza">Raza: ${raza}</p> <p class="gatoPeso">Peso: ${peso} Kg</p> </div> `; }); }) .catch(err => console.error('读取数据失败:', err));
- 解决浏览器本地文件限制:部分浏览器(比如Chrome)默认禁止脚本读取本地文件,需要启动浏览器时添加参数:
- Windows:右键Chrome快捷方式,属性里的目标后添加
--allow-file-access-from-files(注意前面有空格) - Mac:在终端运行
open -a "Google Chrome" --args --allow-file-access-from-files
- Windows:右键Chrome快捷方式,属性里的目标后添加
方案2:使用浏览器端数据库(IndexedDB)
如果数据需要偶尔更新,可以把MySQL的数据导入到浏览器的IndexedDB中,之后前端直接从IndexedDB读取数据渲染。但这个需要一次性导入数据,适合数据不频繁变动的场景:
- 写一个临时的Node脚本把数据库数据转成JSON,再通过前端脚本导入到IndexedDB
- 之后每次打开HTML,直接从IndexedDB读取数据渲染
关键注意点
- Node.js是后端环境,没有浏览器的
document、fetch等API,所以不能在Node脚本里直接操作DOM,必须把数据获取和前端渲染分开。 - 你之前的代码里存在字段名大小写不匹配的问题:SQL查询的是
Color,但渲染时用的是color,会导致变量未定义,一定要统一字段名。
内容的提问来源于stack exchange,提问作者Nicolas Chasnovsky
相关产品推荐
相关产品推荐

