后端必须重命名文件,前端无法修改file.name;应使用multer(Node.js)或move_uploaded_file(PHP)在服务端生成安全文件名,结合哈希、时间戳、随机字符串及真实MIME类型校验,并存于Web不可访问目录,通过受控路由提供下载。

后端必须重命名,前端改名只是假象
浏览器上传时,input type="file" 提交的原始文件名(file.name)会随请求一起发到服务器,但这个名称完全不可信——用户可任意修改、伪造,甚至传入 ../../../etc/passwd 这类路径。所以任何“在前端 JavaScript 里改 file.name”的操作都无效:file.name 是只读属性,赋值会被忽略。
Node.js/Express 中用 multer 重命名文件
常见方案是用 multer 中间件,在接收文件时生成新名。关键不是替换原名,而是控制 destination 和 filename 回调:
-
destination决定存哪,别写死成./uploads,应校验路径合法性(防../路径遍历) -
filename回调里不要拼接原始file.originalname,而要用哈希 + 时间戳 + 随机字符串生成唯一名,例如uuidv4() + '-' + Date.now() + '.png' - 若需保留原始扩展名,只能从
file.mimetype或二进制头(魔术字节)推断,绝不能信任file.originalname的后缀
PHP 中用 move_uploaded_file() 配合自定义逻辑
PHP 没有内置重命名钩子,得手动处理:
- 先检查
$_FILES['myFile']['error'] === UPLOAD_ERR_OK,确认上传成功 - 用
pathinfo($_FILES['myFile']['name'], PATHINFO_EXTENSION)获取扩展名不可靠,应结合finfo_open()校验真实类型 - 构造安全文件名:去掉所有非字母数字字符,加前缀和时间戳,例如
'upload_' . time() . '_' . rand(1000,9999) . '.' . $safe_ext - 最终调用
move_uploaded_file($_FILES['myFile']['tmp_name'], $target_path)—— 这一步才是真正的“重命名+移动”
重命名后还要注意存储位置和访问控制
即使文件名已随机化,如果直接存在 Web 根目录下(如 /var/www/html/uploads/),攻击者仍可能通过猜测 URL 访问或执行恶意文件。正确做法是:
立即学习“前端免费学习笔记(深入)”;
- 把上传文件存到 Web 不可直接访问的目录(如
/var/www/private_uploads/) - 通过后端路由(如
/api/download?id=abc123)控制下载,校验权限和文件存在性 - 对图片等静态资源,可配合 Nginx 的
alias或X-Accel-Redirect安全输出,避免暴露物理路径
真正难的不是生成一个新名字,而是确保这个名字不带漏洞、不泄露信息、不被绕过——每一步校验缺一不可。



















