Задать вопрос

Можно ли из JS передать обработанное изображение в $_FILES?

Делаю обработчик изображений с помощью canvas и возник вопрос, могу ли я обработанное изображение сразу же вернуть в массив $_FILES и уже после отправки формы работать с ним? Сейчас я сделал через временную папку в которую изначально складывается обработанное изображение, а уже после отправки формы из этой папки берутся изображения и производится дальнейшая работа с ними. Но этот вариант не нравится, т.к. нужно постоянно следить за этой папкой (очищать от тех файлов которые небыли отправлены пользователями, потенциально кто нибудь может накидать туда куча файлов).
В общем хотелось бы обойтись без временной папки, а работать через upload_tmp_dir (tmp/php/uploads). Пробовал через upload.php передать в тело input type="hidden" name="my_photo[]" value="'.$_FILES['photo']['tmp_name'].'", но после отправки формы upload_tmp_dir уже пустой.

Вот как сделано сейчас:
$(document).ready(function(){
	$('#uploadItem').change(function(){		
		$.each(this.files, function(i, file) {				
			// тут проверки
			sendResized(file);
		})
		$('#uploadItem').val('');
	});
});

function sendResized(file){
	var reader = new FileReader();
	reader.onload = function() {
		var maxWidth = 1000;
		var tempImg = new Image();
		tempImg.src = reader.result;
		tempImg.onload = function() {			
			var tempW = tempImg.width;
			var tempH = tempImg.height;
			if (tempW > tempH) {
				if (tempW > maxWidth) {
					tempH *= maxWidth / tempW;
					tempW = maxWidth;
				}
			} else {
				if (tempH > maxWidth) {
					tempW *= maxWidth / tempH;
					tempH = maxWidth;
				}
			}
			tempW = Math.round(tempW);
			tempH = Math.round(tempH);

			var canvas = document.createElement('canvas');
			canvas.width = tempW;
			canvas.height = tempH;
			var ctx = canvas.getContext("2d");
			ctx.drawImage(this, 0, 0, tempW, tempH);
			canvas.toBlob(function(blob) { 
				var data = new FormData();
				data.append('photo', blob);
				$.ajax({
					type: 'POST',
					url: 'upload.php',
					data: data,
					cache: false,
					contentType: false,
					processData: false,	
					success: function(html){
						// тут код success
					}
				});
			}, 'image/jpeg', 0.95);	
		}
	}
   reader.readAsDataURL(file);	
}


А в upload.php по простому
// сократил проверки и другие операции
move_uploaded_file($_FILES['photo']['tmp_name'], $dir.$filename.'.jpg';
  • Вопрос задан
  • 502 просмотра
Подписаться 3 Средний 1 комментарий
Решения вопроса 1
@alpeg
Да, можно.

var data = new FormData();
// вариант 1 (если blob был получен из canvas.toBlob(), то он уже будет иметь правильный mime-type)
data.append("file_field_blob", blob, "filename1.jpg");
// вариант 2
data.append("file_field_file_1", new File([blob], "(будет-проигнорировано).jpg", {type:'image/jpeg'}), "filename2.jpg");
// или так
data.append("file_field_file_2", new File([blob], "filename3.jpg", {type:'image/jpeg'}));
var request = new XMLHttpRequest();
request.onload = function() {
	if (this.status >= 200 && this.status < 400){
		document.write(this.response);
	}
};
request.open("POST", "phpinfo.php");
request.send(data);

Результат:
$_SERVER['HTTP_CONTENT_TYPE'] = multipart/form-data; boundary=--...
$_FILES['file_field_blob'] = Array (
    [name] => filename1.jpg
    [type] => image/jpeg
    [tmp_name] => C:\...\php....tmp
    [error] => 0
    [size] => 46196
)
$_FILES['file_field_file_1'] = Array (
    [name] => filename2.jpg
    [type] => image/jpeg
    [tmp_name] => C:\...\php....tmp
    [error] => 0
    [size] => 46196
)
$_FILES['file_field_file_2'] = Array (
    [name] => filename3.jpg
    [type] => image/jpeg
    [tmp_name] => C:\...\php....tmp
    [error] => 0
    [size] => 46196
)

new File() - https://developer.mozilla.org/en-US/docs/Web/API/F...
FormData - https://developer.mozilla.org/en-US/docs/Web/API/F...

Upd:
Не используйте readAsDataURL! Вместо него надо использовать FileReader.readAsArrayBuffer().
А если нужна ссылка, например для <img> то нужно создавать её через URL.createObjectURL (и после использования удалять через URL.revokeObjectURL())
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
sanchezzzhak
@sanchezzzhak
Ля ля ля...
нет. в FILES попадают только инпуты файлов формы

но как вы отправляете данные их нужно ловить через
$rawData = file_get_contents("php://input");
посмотрите примеры как через js ajax отправить в php://input
Скорее всего var data = new FormData(); не нужен будет
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы