PHP+JS:如何以 HTML 形式将文件上传为 Content-Type Multipart(通过 JS)?
PHP+JS: How to do Fileuploads in HTML Form as Content-Type Multipart (via JS)?
有一个通过 POST 提交的 HTML 表单(用户点击
提交按钮)。
此外还有一个通过 canvas 的 Javascript 读取的图像
对象 (getImageData()).
问题:
如何将此图像数据 "inject" 放入 HTML 表单中,以便将其上传为 Content-Type:multipart/form-data 并可以通过现有的 PHP 框架数据提取逻辑?
在 POST 请求中使用 CHrome 捕获的 <input type="file"
上传示例 => 它应该看起来像这样
------WebKitFormBoundaryBBAQ5B4Ax1NgxFmD
Content-Disposition: form-data; name="images"; filename="fooimage.png"
Content-Type: image/png
问题:
我知道如何在单独的请求中上传它(通过 ajax,与表格分开)。我知道如何将其作为 base64 数据上传并在表单中手动处理。
但我不知道如何沿着现有表单发送图像数据,以便它查找与通过 <input type="file"...
[= 发送的图像完全相同的 PHP 服务器端脚本15=]
原因:Symphony(FileUpload 对象)检查文件是否通过 POST 表单上传,如果我用数据手动实例化对象则失败。
所以最好的解决方案是(关于很多其他事情,比如测试,避免不必要的逻辑),如果数据将像常规表单上传一样传递。如何做到这一点?
谢谢!
您可以使用 FormData 对象获取表单的值,然后将 canvas 的 blob 版本附加到 FormData 中。
此 blob 将被服务器视为文件。
很遗憾,所有的浏览器还是不支持原生的canvas.toBlob()
method, and even worth, all 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);
}
有一个通过 POST 提交的 HTML 表单(用户点击 提交按钮)。
此外还有一个通过 canvas 的 Javascript 读取的图像 对象 (getImageData()).
问题:
如何将此图像数据 "inject" 放入 HTML 表单中,以便将其上传为 Content-Type:multipart/form-data 并可以通过现有的 PHP 框架数据提取逻辑?
在 POST 请求中使用 CHrome 捕获的 <input type="file"
上传示例 => 它应该看起来像这样
------WebKitFormBoundaryBBAQ5B4Ax1NgxFmD
Content-Disposition: form-data; name="images"; filename="fooimage.png"
Content-Type: image/png
问题: 我知道如何在单独的请求中上传它(通过 ajax,与表格分开)。我知道如何将其作为 base64 数据上传并在表单中手动处理。
但我不知道如何沿着现有表单发送图像数据,以便它查找与通过 <input type="file"...
[= 发送的图像完全相同的 PHP 服务器端脚本15=]
原因:Symphony(FileUpload 对象)检查文件是否通过 POST 表单上传,如果我用数据手动实例化对象则失败。
所以最好的解决方案是(关于很多其他事情,比如测试,避免不必要的逻辑),如果数据将像常规表单上传一样传递。如何做到这一点?
谢谢!
您可以使用 FormData 对象获取表单的值,然后将 canvas 的 blob 版本附加到 FormData 中。
此 blob 将被服务器视为文件。
很遗憾,所有的浏览器还是不支持原生的canvas.toBlob()
method, and even worth, all 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);
}