
本文详解两种可靠方式:通过 formdata 以 multipart/form-data 格式上传 blob(使 `$_files` 正常工作),或直接发送纯文本并用 `php://input` 读取,解决 `$_files` 为空的问题。
在前端用 javaScript 动态创建 Blob(如日志、配置片段、导出文本)后,若希望将其作为“文件”上传至 php 后端并出现在 $_FILES 数组中,必须使用 multipart/form-data 编码格式——这是 PHP 自动解析并填充 $_FILES 的唯一前提。而你原始代码中直接将 Blob 作为 body 发送,并设置 Content-Type: text/plain,实际触发的是 raw POST 请求,PHP 不会将其视为文件上传,因此 $_FILES 恒为空数组。
✅ 方案一:使用 FormData 实现标准文件上传(推荐用于需兼容 $_FILES 的场景)
FormData 会自动设置正确的 Content-Type(含 boundary),并将 Blob 封装为表单字段,PHP 即可像处理 一样处理:
// JavaScript(前端) const myFile = new Blob(["A file"], { type: "text/plain" }); const formData = new FormData(); formData.append("uploaded_file", myFile, "custom-file.txt"); // 第三个参数为文件名(可选但强烈建议) fetch("server_location.php", { method: "POST", body: formData // ⚠️ 不要手动设置 headers!FormData 会自动处理 }) .then(res => res.text()) .then(text => console.log("Server response:", text)) .catch(err => console.error("Upload failed:", err));
对应 PHP 接收端(server_location.php):
htmlspecialchars($destPath); } else { http_response_code(500); echo "❌ Failed to save file."; } } else { http_response_code(400); echo "❌ Invalid file type or size."; } } else { http_response_code(400); echo "❌ No valid file uploaded. Error: " . $_FILES['uploaded_file']['error']; }
? 关键点: FormData.append() 的第三个参数(文件名)决定了 $_FILES['uploaded_file']['name'] 的值;不传则默认为 "blob"。 切勿手动设置 headers —— FormData 会自动生成带 boundary 的 Content-Type: multipart/form-data; boundary=...,覆盖它会导致解析失败。 确保 PHP 配置允许上传(file_uploads = On,upload_max_filesize 足够)。
✅ 方案二:直接发送纯文本内容(适合轻量、无文件元信息需求)
若你仅需传输文本内容,无需文件名、类型等元数据,且不强依赖 $_FILES,可跳过 multipart,改用 raw POST:
立即学习“PHP免费学习笔记(深入)”;
// JavaScript(前端) const content = "A file"; fetch("server_location.php", { method: "POST", body: content, headers: { "Content-Type": "text/plain; charset=utf-8" } }) .then(res => res.text()) .then(text => console.log(text));
PHP 端读取原始请求体:
lspecialchars(substr($data, 0, 100));
⚠️ 注意:php://input 在 enctype="multipart/form-data" 时不可用,因此该方案与方案一互斥。
总结与选型建议
| 场景 | 推荐方案 | 前端关键 | PHP 关键 |
|---|---|---|---|
| 需要文件名、类型、临时路径,或需与传统表单上传逻辑统一 | ✅ FormData + $_FILES | new FormData().append(...),不设 headers | 检查 $_FILES[key],用 move_uploaded_file() |
| 仅需传输纯文本内容,追求简洁、避免临时文件 | ✅ Raw POST + php://input | fetch(..., { body: String }) + text/plain header | file_get_contents("php://input") |
无论哪种方式,请始终校验输入、限制大小、过滤文件名(方案一)、设置合适的 HTTP 状态码,并在生产环境启用 https 保障传输安全。