accept属性仅影响文件选择框显示,无法限制代码文件类型;真正决定可执行代码的是后端沙箱或编译器。

accept 属性无法限制在线运行环境支持的代码文件类型——它连前端校验都算不上,只影响文件选择框的默认显示。真正决定“哪些代码能跑”的,是后端沙箱或编译器本身,不是 accept。
accept="text/*" 为什么选不到 .py 或 .js 文件
浏览器对 text/* 的理解极不统一:text/plain 可能匹配 .txt,但 .py 在 macOS 上常报 text/x-python,Windows 可能为空,Safari 直接忽略通配符。更糟的是,text/html 也会被匹配进来,而 HTML 文件若被误执行,可能触发 XSS。
实际建议用显式组合:
-
accept="text/plain,text/x-python,.py"(Python) -
accept="text/plain,application/javascript,.js"(JavaScript) -
accept="text/plain,text/x-c,text/x-c++,.c,.cpp,.cc"(C/C++)
注意:逗号后不能有空格;text/x-python 比 text/plain 更准,但部分安卓 WebView 不识别,所以必须加 .py 补位。
在线运行环境必须禁用的 accept 写法
以下写法看似合理,实则在关键场景失效:
-
accept=".py,.js"→ iOS Safari 和多数 WebView 完全忽略扩展名 -
accept="text/*"→ 匹配到text/html、text/css,甚至伪造的malware.py(实际是 HTML) -
accept="application/octet-stream"→ 等于开放所有二进制文件,包括可执行 ELF 或 Mach-O
尤其警惕 text/* 类型——它不等于“纯文本代码”,而是“所有 MIME 以 text/ 开头的文件”,其中 text/markdown、text/csv 都可能被误传,且内容不可执行性无法保证。
使用 Puppeteer + Chrome 将 HTML 渲染为中文 PDF,自动处理图表等待、Tab 展开、动画、测高、白边消除、防分页,适用于看板、报表、网页和交互图表转 PDF。
前端 JS 必须拦截的两类危险文件
即使 accept 设对了,用户仍可通过拖拽、粘贴或 DevTools 清除属性上传非法文件。change 事件里必须检查:
- 扩展名黑名单:
file.name.match(/\.(html|htm|svg|php|sh|exe|bat)$/i)—— 这些文件哪怕重命名为main.py,也不能交给沙箱执行 - 内容伪装:
FileReader读前 4 字节,若为%PDF、\x89PNG、PK\x03\x04,直接拒绝 —— 说明是 PDF/图片/ZIP 假扮代码文件
别依赖 file.type:把 hack.sh 改成 script.py 后,file.type 很可能返回 text/x-python,但内容仍是 shell 脚本。
后端才是运行环境真正的闸门
前端所有过滤对在线运行环境毫无意义:curl 可绕过全部 HTML,Postman 可伪造任意 Content-Type,沙箱进程收到的仍是原始字节流。
服务端必须做三件事:
- 用
file-type(Node.js)、python-magic(Python)或libmagic(C)解析文件头,确认真实 MIME 与扩展名逻辑一致(例如.py文件头必须是 ASCII 可读文本,不能是 ZIP) - 禁止任何含
<script></script>、<svg>、<code><?php的文件进入编译流程,哪怕扩展名合法 - 运行前重命名文件为随机哈希 + 白名单后缀(如
a7f2b1.py),剥离原始文件名中可能存在的路径遍历(../../etc/passwd)或编码绕过
最容易被忽略的一点:在线运行环境通常用 stdin 传入代码,而非读取磁盘文件。此时 accept 根本不参与流程——用户粘贴一段 JS 到编辑器里点“运行”,accept 连被触发的机会都没有。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










