PHP+JS:如何在 HTML 表单中将文件上传为 Content-Type Multipart(通过 JS)?

IT技术 javascript html post html5-canvas multipartform-data
2021-01-23 22:10:39
  1. 拥有一个通过 POST 提交的 HTML 表单(用户单击提交按钮)。

  2. 此外,还有一张通过画布对象的 Javascript 读取的图像 (getImageData())。

问题:

如何将此图像数据“注入”到 HTML 表单中,以便将其作为 Content-Type:multipart/form-data 上传并可以通过现有的 PHP 框架数据提取逻辑进行处理?

<input type="file"在 POST 请求中使用 CHrome 捕获上传示例=> 它应该如下所示

------WebKitFormBoundaryBBAQ5B4Ax1NgxFmD
Content-Disposition: form-data; name="images"; filename="fooimage.png"
Content-Type: image/png

问题: 我知道如何在单独的请求中上传它(通过 ajax,与表单分开)。我知道如何将它上传为 base64 数据并在表单中手动处理它。

但我不知道如何沿现有表单发送图像数据,以便它查找与通过发送的图像完全相同的 PHP 服务器端脚本 <input type="file"...

原因:Symphony (FileUpload Object) 检查文件是否通过 POST 表单上传,如果我用数据手动实例化对象,则失败。
所以最好的解决方案是(关于许多其他事情,比如测试,避免不必要的逻辑),如果数据将像常规表单上传一样传递。这个怎么做?

谢谢!

1个回答

您可以使用FormData对象来获取表单的值,然后将画布的 blob 版本附加到 FormData 中。

该 blob 将被服务器视为文件。

不幸的是,所有浏览器仍然不支持本地canvas.toBlob()方法,甚至值得,所有实现都不相同。
所有主要的浏览器都支持的toBlob方法,你可以找到一个填充工具上MDN旧版本浏览器。

// the function to create and send our FormData
var send = function(form, url, canvas, filename, type, quality, callback) {

  canvas.toBlob(function(blob){
    var formData = form ? new FormData(form) : new FormData();
    formData.append('file', blob, filename);

    var xhr = new XMLHttpRequest();
    xhr.onload = callback;
    xhr.open('POST', url);
    xhr.send(formData);

    }, type, quality);
};

// How to use it //

var form = document.querySelector('form'),   // the form to construct the FormData, can be null or undefined to send only the image
  url = 'http://example.com/upload.php',     // required, the url where we'll send it
  canvas = document.querySelector('canvas'), // required, the canvas to send
  filename = (new Date()).getTime() + '.jpg',// required, a filename
  type = 'image/jpeg',                       // optional, the algorithm to encode the canvas. If omitted defaults to 'image/png'
  quality = .5,                              // optional, if the type is set to jpeg, 0-1 parameter that sets the quality of the encoding
  callback = function(e) {console.log(this.response);}; // optional, a callback once the xhr finished

send(form, url, canvas, filename, type, quality, callback);

PHP 方面将是:

if ( isset( $_FILES["file"] ) ){
    $dir = 'some/dir/';
    $blob = file_get_contents($_FILES["file"]['tmp_name']);
    file_put_contents($dir.$_FILES["file"]["name"], $blob);
    }
@eddyparkinson 很高兴它有所帮助,但我回滚了您的编辑:callback如果您想在浏览器中显示响应,已经有一个可以使用参数,但这绝不应该是此功能的默认行为。
2021-03-14 22:10:39
任何想法如何在 ms Edge 上进行此操作 - 它给出错误对象不支持属性或方法“toBlob”
2021-03-25 22:10:39
@eddyparkinson 使用我链接到的 polyfill:developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/...
2021-03-29 22:10:39
作品 - 谢谢。我添加了示例代码以像正常表单一样在浏览器中显示响应。
2021-04-06 22:10:39