HTML中SQL编辑器本质是contenteditable或textarea容器,真正功能由JavaScript库(如Monaco)或后端API实现;纯HTML无法语法高亮、自动补全或执行SQL。

HTML里放SQL编辑器,本质是用textarea还是contenteditable?
纯HTML做不到语法高亮、自动补全或执行SQL——它只是容器。真正起作用的是JavaScript库(比如Monaco、CodeMirror、Ace)或后端API配合前端渲染。如果你只写一个<textarea>,那只是个能换行打字的框,连关键字变色都做不到。
常见错误现象:textarea里粘贴SELECT * FROM users WHERE id = 1;,结果提交时被XSS过滤、空格被压缩、换行丢失;或者用户误删了分号,前端完全无法感知。
- 用
textarea:适合极简场景,需手动处理换行符(vs)、转义(<→)、长度截断 - 用
div[contenteditable="true"]:可嵌入HTML高亮标签,但光标定位、撤销栈、剪贴板事件兼容性差,Safari下execCommand已废弃 - 真实项目推荐直接引入
monaco-editor(VS Code同源),它内置SQL语言支持,只需加载vs/basic-languages/sql/sql.js
Monaco Editor加载SQL语言支持要配哪些关键项?
不配置语言模式,Monaco只会当纯文本处理——没有关键字识别、没有括号匹配、没有FROM后面自动提示表名。核心是两步:注册语言 + 设置model选项。
容易踩的坑:monaco.editor.create()传入的language值必须是'sql'(小写),不是'SQL'或'mysql';且必须提前调用monaco.languages.register({ id: 'sql' }),否则控制台报Unknown language。
立即学习“前端免费学习笔记(深入)”;
- 必须加载
monaco-editor/esm/vs/basic-languages/sql/sql.js(ESM方式)或通过loader.config({ paths: { 'vs': 'node_modules/monaco-editor/min/vs' } })配路径 - 创建editor时指定
language: 'sql',同时设置value初始内容和theme: 'vs-dark'避免白底黑字看不清关键字 - 如需自定义SQL方言(比如加
INSERT IGNORE),得调用monaco.languages.setMonarchTokensProvider('sql', {...})重写tokenizer规则
前端执行SQL?别硬刚,先搞清这三件事
浏览器里不能直连数据库,所谓“前端执行SQL”实际是把语句发给后端API,再把JSON结果渲染成表格。强行在前端模拟执行(比如用sql.js编译SQLite到WebAssembly)只适合离线小数据,且不支持JOIN、索引、事务等关键能力。
典型错误操作:把fetch('/api/query', { method: 'POST', body: sqlText })写死在按钮点击里,没做SQL注入防护——后端若直接拼接字符串,SELECT * FROM users WHERE name = '' OR '1'='1'就炸了。
- 前端要做基础校验:检查是否含
DROP、DELETE、UPDATE等危险关键词(正则/\b(DROP|DELETE|UPDATE|ALTER)\b/i),拦截后给出明确提示 - 后端必须用参数化查询(如PostgreSQL的
$1占位符),绝不用字符串拼接 - 响应体结构要统一:
{ "success": true, "rows": [...], "columns": ["id","name"], "time_ms": 12 },方便前端渲染表格并显示耗时
为什么你写的SQL编辑器总在移动端崩?
因为textarea在iOS Safari上会触发缩放、软键盘顶起页面、光标错位;Monaco在Android Chrome里可能因transform: scale()导致触摸坐标偏移。这不是代码逻辑问题,而是CSS和事件层适配缺失。
最容易被忽略的点:没禁用双击缩放、没处理resize事件重绘编辑器、没监听keyboardDidShow(React Native)或focus后滚动到可视区。
- 在
<head>里加<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> - Monaco实例创建后,手动调用
editor.layout()响应窗口大小变化,尤其在软键盘弹出/收起时 - 对
textarea方案,加style="font-size: 16px; line-height: 1.5;"防止iOS自动放大,再用onfocus="this.scrollIntoView({ behavior: 'smooth' })"保光标可见
复杂点不在语法解析,而在输入法、软键盘、缩放、焦点管理这些“看不见的交互链”。少配一个viewport,用户在iPhone上点第一行就看不到光标。



















