I try to make an image-upload functionality similar to the one GMail uses. You copy (CTRL-C) an image from your desktop and paste (CTRL-V) it onto the website. The image is then uploaded via a XMLHttpRequest to a php-script that handles the incoming file, whereby "handling" means renaming and storing on the server.
我尝试制作类似于GMail使用的图像上传功能。您从桌面复制(CTRL-C)图像并将其粘贴(CTRL-V)到网站上。然后通过XMLHttpRequest将图像上传到处理传入文件的php脚本,其中“处理”意味着重命名并存储在服务器上。
I can already fetch the image (and -data), but I am unable to successfully submit and receive the XMLHttpRequest. My Javascript code looks like that:
我已经可以获取图像(和-data),但我无法成功提交和接收XMLHttpRequest。我的Javascript代码看起来像这样:
document.onpaste = function(e){
var items = e.clipboardData.items;
console.log(JSON.stringify(items));
if (e.clipboardData.items[1].kind === 'file') {
// get the blob
var imageFile = items[1].getAsFile();
console.log(imageFile);
var reader = new FileReader();
reader.onload = function(event) {
console.log(event.target.result); // data url!
submitFileForm(event.target.result, 'paste');
};
}
};
function submitFileForm(file, type) {
var formData = new FormData();
formData.append('file', file);
formData.append('submission-type', type);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'php/image-upload.php');
xhr.onload = function () {
if (xhr.status == 200) {
console.log('all done: ');
} else {
console.log('Nope');
}
};
xhr.send(formData);
}
The handling php (php/image-upload.php
) looks like that:
处理php(php / image-upload.php)看起来像这样:
$base64string = $_POST['file'];
file_put_contents('img.png', base64_decode($base64string));
I think the $_POST['file']
stays empty, but I am not sure. What's more, I also encounter the "blob size" (displayed with console.log()) is way larger than the actual image size. But maybe that's no matter or caused by encodings.
我认为$ _POST ['file']保持空白,但我不确定。更重要的是,我还遇到“blob size”(用console.log()显示)比实际图像大小大。但也许这无论是编码还是由编码造成的。
The developer console displays this.
开发者控制台显示此信息。
{"0":{"type":"text/plain","kind":"string"},"1":{"type":"image/png","kind":"file"},"length":2} image-upload.js:8
Blob {type: "image/png", size: 135619, slice: function}
If I view the file-info by right-clicking the actual image file, it shows 5,320 bytes (8 KB on disk)
in size.
如果我通过右键单击实际图像文件来查看文件信息,它将显示5,320个字节(磁盘上为8 KB)。
I do not necessarily need to use a XMLHttpRequest
, it was just what came to my mind first. If there's a better way of achieving realtime image-uploading to a server with javascript, please let us know.
我不一定需要使用XMLHttpRequest,这是我首先想到的。如果有更好的方法使用javascript实现实时图像上传到服务器,请告诉我们。
4 个解决方案
#1
4
you copy (CTRL-C) an image from your desktop and paste (CTRL-V) it onto the website.
您从桌面复制(CTRL-C)图像并将其粘贴(CTRL-V)到网站上。
No, that is impossible. What you can paste is e.g. screenshots and images from the web, that's what gmail does.
不,那是不可能的。您可以粘贴的是例如来自网络的截图和图片,这就是gmail所做的。
Your biggest mistake is using FileReader when you already have a file, the $_FILES
array is filled when there is a proper HTTP upload not for ad hoc base64 POST param. To do a proper HTTP upload, you just .append()
a file or blob object (File
s are Blob
s).
您最大的错误是在已有文件时使用FileReader,当正确的HTTP上载不是ad hoc base64 POST参数时,$ _FILES数组被填充。要进行正确的HTTP上传,只需.append()文件或blob对象(文件是Blob)。
This is a stand-alone PHP file that should just work, host the file, open it is a page, take a screenshot, then paste it while on the page and after a few seconds the image should appear on the page.
这是一个独立的PHP文件,应该可以工作,托管文件,打开它是一个页面,截取屏幕截图,然后在页面上粘贴它,几秒钟后图像应该出现在页面上。
<?php
if( isset( $_FILES['file'] ) ) {
$file_contents = file_get_contents( $_FILES['file']['tmp_name'] );
header("Content-Type: " . $_FILES['file']['type'] );
die($file_contents);
}
else {
header("HTTP/1.1 400 Bad Request");
}
print_r($_FILES);
?>
<script>
document.onpaste = function (e) {
var items = e.clipboardData.items;
var files = [];
for( var i = 0, len = items.length; i < len; ++i ) {
var item = items[i];
if( item.kind === "file" ) {
submitFileForm(item.getAsFile(), "paste");
}
}
};
function submitFileForm(file, type) {
var extension = file.type.match(/\/([a-z0-9]+)/i)[1].toLowerCase();
var formData = new FormData();
formData.append('file', file, "image_file");
formData.append('extension', extension );
formData.append("mimetype", file.type );
formData.append('submission-type', type);
var xhr = new XMLHttpRequest();
xhr.responseType = "blob";
xhr.open('POST', '<?php echo basename(__FILE__); ?>');
xhr.onload = function () {
if (xhr.status == 200) {
var img = new Image();
img.src = (window.URL || window.webkitURL)
.createObjectURL( xhr.response );
document.body.appendChild(img);
}
};
xhr.send(formData);
}
</script>
#2
2
i have posted a full working example. The problem before was you needed to construct the blob properly. by injecting the file data inside an array notation
我已经发布了一个完整的工作示例。之前的问题是你需要正确构建blob。通过在数组表示法中注入文件数据
document.onpaste = function(e){
var items = e.clipboardData.items;
console.log(JSON.stringify(items));
if (e.clipboardData.items[0].kind === 'file') {
// get the blob
var imageFile = items[0].getAsFile();
console.log(imageFile);
var reader = new FileReader();
reader.onload = function(event) {
console.log(event.target.result); // data url!
submitFileForm(event.target.result, 'paste');
};
reader.readAsBinaryString(imageFile);
}
};
function submitFileForm(file, type) {
var formData = new FormData();
var myBlob = new Blob([file], { "type" : "image/png"} );
formData.append('file', myBlob, 'file.jpg');
formData.append('submission-type', type);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/task/file');
xhr.onload = function () {
if (xhr.status == 200) {
console.log('all done: ');
} else {
console.log('Nope');
}
};
xhr.send(formData);
}
#3
-1
Is it possible that the image file size is greater than your 'upload_max_filesize' setting?(usually defaults to 2 meg)
图像文件大小是否可能大于“upload_max_filesize”设置?(通常默认为2 meg)
#4
-1
I guess the file is in the $_FILE array not in the $_POST since it is a file. If not, you may convert the image to a string an send the imagestring as GET request.
我想这个文件在$ _FILE数组中不在$ _POST中,因为它是一个文件。如果没有,您可以将图像转换为字符串,将imagestring作为GET请求发送。
#1
4
you copy (CTRL-C) an image from your desktop and paste (CTRL-V) it onto the website.
您从桌面复制(CTRL-C)图像并将其粘贴(CTRL-V)到网站上。
No, that is impossible. What you can paste is e.g. screenshots and images from the web, that's what gmail does.
不,那是不可能的。您可以粘贴的是例如来自网络的截图和图片,这就是gmail所做的。
Your biggest mistake is using FileReader when you already have a file, the $_FILES
array is filled when there is a proper HTTP upload not for ad hoc base64 POST param. To do a proper HTTP upload, you just .append()
a file or blob object (File
s are Blob
s).
您最大的错误是在已有文件时使用FileReader,当正确的HTTP上载不是ad hoc base64 POST参数时,$ _FILES数组被填充。要进行正确的HTTP上传,只需.append()文件或blob对象(文件是Blob)。
This is a stand-alone PHP file that should just work, host the file, open it is a page, take a screenshot, then paste it while on the page and after a few seconds the image should appear on the page.
这是一个独立的PHP文件,应该可以工作,托管文件,打开它是一个页面,截取屏幕截图,然后在页面上粘贴它,几秒钟后图像应该出现在页面上。
<?php
if( isset( $_FILES['file'] ) ) {
$file_contents = file_get_contents( $_FILES['file']['tmp_name'] );
header("Content-Type: " . $_FILES['file']['type'] );
die($file_contents);
}
else {
header("HTTP/1.1 400 Bad Request");
}
print_r($_FILES);
?>
<script>
document.onpaste = function (e) {
var items = e.clipboardData.items;
var files = [];
for( var i = 0, len = items.length; i < len; ++i ) {
var item = items[i];
if( item.kind === "file" ) {
submitFileForm(item.getAsFile(), "paste");
}
}
};
function submitFileForm(file, type) {
var extension = file.type.match(/\/([a-z0-9]+)/i)[1].toLowerCase();
var formData = new FormData();
formData.append('file', file, "image_file");
formData.append('extension', extension );
formData.append("mimetype", file.type );
formData.append('submission-type', type);
var xhr = new XMLHttpRequest();
xhr.responseType = "blob";
xhr.open('POST', '<?php echo basename(__FILE__); ?>');
xhr.onload = function () {
if (xhr.status == 200) {
var img = new Image();
img.src = (window.URL || window.webkitURL)
.createObjectURL( xhr.response );
document.body.appendChild(img);
}
};
xhr.send(formData);
}
</script>
#2
2
i have posted a full working example. The problem before was you needed to construct the blob properly. by injecting the file data inside an array notation
我已经发布了一个完整的工作示例。之前的问题是你需要正确构建blob。通过在数组表示法中注入文件数据
document.onpaste = function(e){
var items = e.clipboardData.items;
console.log(JSON.stringify(items));
if (e.clipboardData.items[0].kind === 'file') {
// get the blob
var imageFile = items[0].getAsFile();
console.log(imageFile);
var reader = new FileReader();
reader.onload = function(event) {
console.log(event.target.result); // data url!
submitFileForm(event.target.result, 'paste');
};
reader.readAsBinaryString(imageFile);
}
};
function submitFileForm(file, type) {
var formData = new FormData();
var myBlob = new Blob([file], { "type" : "image/png"} );
formData.append('file', myBlob, 'file.jpg');
formData.append('submission-type', type);
var xhr = new XMLHttpRequest();
xhr.open('POST', '/task/file');
xhr.onload = function () {
if (xhr.status == 200) {
console.log('all done: ');
} else {
console.log('Nope');
}
};
xhr.send(formData);
}
#3
-1
Is it possible that the image file size is greater than your 'upload_max_filesize' setting?(usually defaults to 2 meg)
图像文件大小是否可能大于“upload_max_filesize”设置?(通常默认为2 meg)
#4
-1
I guess the file is in the $_FILE array not in the $_POST since it is a file. If not, you may convert the image to a string an send the imagestring as GET request.
我想这个文件在$ _FILE数组中不在$ _POST中,因为它是一个文件。如果没有,您可以将图像转换为字符串,将imagestring作为GET请求发送。