
本文详解两种可靠方式:通过 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):
? 关键点: 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免费学习笔记(深入)”;
php中级教程之ajax技术下载AJAX即“Asynchronous Javascript And XML”(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。它不是新的编程语言,而是一种使用现有标准的新方法,最大的优点是在不重新加载整个页面的情况下,可以与服务器交换数据并更新部分网页内容,不需要任何浏览器插件,但需要用户允许JavaScript在浏览器上执行。《php中级教程之ajax技术》带你快速
// 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 端读取原始请求体:
⚠️ 注意: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 保障传输安全。











