fetch 如何发送复杂表单到PHP后台,接收并存储?

请问:一个表单里既有普通字段,也有一个文件上传的字段,是否可以使用fetch实现提交表单?
前提是使用 json 格式发送,也就是说文件的字段需要转换成字符串。

后台 PHP 使用 file_get_contents('php://input'), true) 进行接收。

请问该把需要上传的文件转换成什么?目前只知道图片可以转成 base64 ,那如果是其他格式呢,比如压缩包应该怎么整?

是不是这类不仅仅是文件上传的表单,不适合使用 fetch 进行操作。
从网上已经查过一些资料,但是并没有找到。

部分参考
https://blog.51cto.com/lxw1844912514/2941481

https://developer.mozilla.org/zh-CN/docs/Web/API/FileReader

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Refer...

阅读 1.4k
avatarAI BotBETA

根据您提供的信息,您可以使用fetch API将复杂表单发送到PHP后台,并使用file_get_contents('php://input')接收并存储。

对于文件上传字段,您可以将文件内容转换为base64编码字符串,然后将其作为json格式的表单数据的一部分发送到后台。您可以使用FileReader API读取文件内容,并将其转换为base64编码字符串。

对于其他格式的文件,例如压缩包,您可以使用JavaScript中的File API来读取文件内容,并将其转换为base64编码字符串。然后,您可以将该字符串作为json格式的表单数据的一部分发送到后台。

需要注意的是,使用fetch API发送文件数据可能会受到浏览器的安全限制。在某些情况下,浏览器可能会阻止跨域请求中包含二进制数据,这可能导致文件无法正确地传输到后台。

如果您需要处理文件上传表单,您可能需要使用其他方法,例如XMLHttpRequest或第三方库,例如axios。

3 个回答
  1. 一般来说不建议把复杂的表单混着文件上传一起做
  2. 最好单独做一个上传功能,上传完成后,把文件地址保存到表单里
  3. 然后一起提交一个大 json
  4. 否则万一文件上传失败,整个表单都要重新上传,很容易出问题

一般的设计都是会为文件上传提供单独的接口,而不是和表单放在一起。

按照你上面的做法,对于任何文件,你都可以把他转为 base64 的方式,然后嵌在 json 里面当成普通字符串发送出去。

但是这样会面临一个最直接的问题,就是文件的体积会增加 30%,这是 base64 带来的问题,而且浏览器可能还需要 100%(打开文件) + 130%(转为 base64) 的内存来满足你的需求,如果文件过大,可能直接导致浏览器卡住、甚至崩溃。同时网络上传也可能需要额外约 30% 的时间来处理。

这是从性能上的考虑。

其次,再从业务角度考虑。

以常见后台表单为例,一般表单项都会很多,假设因为用户填写的某些表单项不符合后端的验证规则,那就意味着,每一次你都需要把这个文件传到后端去,后端即使不去转存这个文件,这个文件也会被保存在临时文件中去,造成额外的消耗。

所以,一般情况下,对于文件上传都是提供单独的接口,使用标准的 FormData。


对于一些特别的格式,比如图文混排中的图片,就可能会直接返回图片地址,以便于在混排的时候,能够准确的知道加入的图片在什么位置。

当然,你也可以返回文件 ID,只是不便于前台展示预览。

如果你是想为了安全,那你可以把地址、ID 放到 Session 里面,在表单提交验证通过后,再在后台填入。


单独提供上传接口也是一种解耦的方式,如果后期需要修改上传接口,比如改为上传到 OSS 等,改造成本也更加的低。

  • 首先主流的做法是,先通过单独的文件上传接口将文件上传,然后将返回的文件地址或者ID用于后续的表单提交。
  • 如果想要同时上传文件和其他字段,那就应该用 FormData 格式来传输;如果想要全部用 json 的话,需要将文件转换为Base64,但是随之而来的会有体积提升、无法分片上传、断点续传等问题。

使用 FormData 示例如下:

const form = new FormData();
form.append("file", file);
form.append("key1", "value1");
form.append("key2", "value2");

fetch("your_php_endpoint.php", {
  method: "POST",
  body: form
});
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏