Я пытаюсь сделать функцию загрузки изображений, аналогичную той, которую использует GMail. Вы копируете (CTRL-C) изображение со своего рабочего стола и вставляете его (CTRL-V) на веб-сайт. Затем изображение загружается через XMLHttpRequest в php-скрипт, который обрабатывает входящий файл, при этом «обработка» означает переименование и сохранение на сервере.
Я уже могу получить изображение (и -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); }
Обработка php ( php/image-upload.php
) выглядит так:
$base64string = $_POST['file']; file_put_contents('img.png', base64_decode($base64string));
Я думаю, что $_POST['file']
остается пустым, но я не уверен. Более того, я также сталкиваюсь с размером «blob size» (отображается с помощью console.log ()) намного больше, чем фактический размер изображения. Но, возможно, это неважно или вызвано кодировками.
Консоль разработчика отображает это.
{"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}
Если я просматриваю файловую информацию, щелкнув правой кнопкой мыши фактический файл изображения, он отобразит 5,320 bytes (8 KB on disk)
.
Мне не обязательно использовать XMLHttpRequest
, это было именно то, что мне пришло в голову. Если есть лучший способ добиться загрузки изображений в реальном времени на сервер с помощью javascript, сообщите нам об этом.
вы копируете (CTRL-C) изображение со своего рабочего стола и вставляете его (CTRL-V) на веб-сайт.
Нет, это невозможно . Что вы можете вставить, например, скриншоты и изображения из Интернета, это то, что делает gmail .
Самая большая ошибка заключается в использовании FileReader, когда у вас уже есть файл, массив $_FILES
заполняется, когда есть надлежащая загрузка HTTP, а не для ad hoc base64 POST param. Чтобы выполнить правильную загрузку HTTP, вы просто .append()
файл или объект blob ( File
s – это Blob
s).
Это автономный 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>
Я опубликовал полный рабочий пример. Проблема была в том, что вам нужно было правильно построить 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); }
Возможно ли, что размер файла изображения больше, чем параметр 'upload_max_filesize' (обычно по умолчанию используется 2 мегабайта)
Я думаю, файл находится в массиве $ _FILE, а не в $ _POST, так как это файл. Если нет, вы можете преобразовать изображение в строку, чтобы отправить изображение в виде запроса GET.