【问题标题】:PHP+JS: How to do Fileuploads in HTML Form as Content-Type Multipart (via JS)?PHP+JS:如何将 HTML 表单中的文件上传为 Content-Type Multipart(通过 JS)?
【发布时间】:2016-01-10 22:51:28
【问题描述】:
  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 数据上传并在表单中手动处理它。

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

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

谢谢!

【问题讨论】:

    标签: javascript html post html5-canvas multipartform-data


    【解决方案1】:

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

    这个 blob 将被服务器视为一个文件。

    很遗憾,所有浏览器仍然不支持原生的canvas.toBlob() 方法,甚至值得,所有implementations 都不一样。
    现在所有主流浏览器都支持 toBlob 方法,老浏览器可以在 mdn 上找到a polyfill

    // 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 参数,但这绝不应该是此函数的默认行为。
    • 知道如何在 ms Edge 上进行这项工作 - 它给出错误 Object does not support property or method 'toBlob'
    • @eddyparkinson 使用我链接到的 polyfill:developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/…
    猜你喜欢
    • 1970-01-01
    • 2019-05-27
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 2011-12-24
    • 2017-02-06
    • 1970-01-01
    • 2019-06-11
    相关资源
    最近更新 更多