accept 属性仅提示无法阻止上传,前端需校验 file.name 后缀,后端须双重校验后缀与 xml 内容并禁用 xxe。
前端用 accept 属性只能提示,不能阻止上传
HTML 的 <input type="file"> 支持 accept 属性,比如 accept=".xml,.xsd",但它只是告诉浏览器“优先显示哪些文件”,用户仍可点击「所有文件」绕过筛选,甚至拖拽任意后缀文件进来。实际上传时,accept 不参与校验,也不影响 File 对象内容。
真正可行的前端拦截必须读取 File.name 或 File.type:
-
File.name可靠:它反映用户选择时的真实文件名,包含后缀(如"data.xml"),适合做后缀白名单判断 -
File.type不可靠:它依赖浏览器根据文件头或扩展名推测的 MIME 类型,XML 文件常被识别为""(空字符串)或"text/plain",不能用于校验
const fileInput = document.querySelector('input[type="file"]');
fileInput.addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
const ext = file.name.split('.').pop().toLowerCase();
if (!['xml', 'xsd', 'xsl'].includes(ext)) {
alert('仅支持 .xml、.xsd、.xsl 文件');
e.target.value = ''; // 清空 input,避免重复触发
return;
}
// 继续上传逻辑...
});
后端必须重验,且不能只看后缀
前端校验可被绕过,后端必须独立验证。只检查文件名后缀(如 filename.endsWith('.xml'))有风险:攻击者可上传 malicious.exe.xml 或伪造后缀的二进制文件。
安全做法是「后缀 + 内容双重校验」:
立即学习“前端免费学习笔记(深入)”;