Загрузить изображение, хранящееся в объекте JavaScript, в PHP
у меня есть запрос, у меня есть Drag & Drop, который хранит мне изображение как объект в переменной JavaScript, как я мог бы сделать, чтобы отправить этот объект в PHP и сохранить изображение в базе данных как тип BLOB?
Так что у меня есть HTML-код
<div class="drag-area">
<div class="icon"><i class="fas fa-cloud-upload-alt"></i></div>
<div class="img"></div>
<header>Drag & Drop to Upload File</header>
<span>OR</span>
<button>Browse File</button>
<input type="file" hidden name="file" />
</div>
и JS так, где вы можете видеть, что переменная file хранит изображение, которое загружается при нажатии кнопки или перетаскивании изображения в dropArea, когда я делаю запрос fetch и я передаю в тело formData по прибытии на сервер, он не сохраняет его и просто показывает мне в ответе как Undefined. Я не очень хорошо знаю PHP в глубине, но если мне нужно иметь возможность исправить недостаток и узнать, потому что он не получает изображение.
const dropArea = document.querySelector(".drag-area"),
dragText = dropArea.querySelector("header"),
icon = dropArea.querySelector(".icon"),
button = dropArea.querySelector("button"),
input = dropArea.querySelector("input"),
img = dropArea.querySelector(".img");
let file;
button.onclick = () => {
input.click();
};
input.addEventListener("change", function () {
// Esta variable file es donde se almacena el archivo como un objeto
file = this.files[0];
dropArea.classList.add("active");
showFile();
});
dropArea.addEventListener("dragover", (event) => {
event.preventDefault();
dropArea.classList.add("active");
dragText.textContent = "Release to Upload File";
});
dropArea.addEventListener("dragleave", () => {
dropArea.classList.remove("active");
dragText.textContent = "Drag & Drop to Upload File";
});
dropArea.addEventListener("drop", (event) => {
event.preventDefault();
file = event.dataTransfer.files[0];
});
// Esta funcion valida la extension de la imagen y la renderiza para insertarla por pantalla
function showFile() {
let fileType = file.type;
let validExtensions = ["image/jpeg", "image/jpg", "image/png"];
if (validExtensions.includes(fileType)) {
let fileReader = new FileReader();
fileReader.onload = () => {
let fileURL = fileReader.result;
var imgTag = `<img src="${fileURL}" alt="" id="foto">`;
img.innerHTML = imgTag;
dragText.classList.add("none");
button.classList.add("none");
icon.classList.add("none");
};
fileReader.readAsDataURL(file);
} else {
alert("This is not an Image File!");
dropArea.classList.remove("active");
dragText.textContent = "Drag & Drop to Upload File";
}
}
// Aqui hago la peticion fetch
enviar.addEventListener("click", () => {
fetch("enviar.php", {
method: "POST",
//Aqui envio el formulario
body: new FormData(form),
})
.then((response) => response.text())
.then((response) => {
console.log(response);
});
});
на сервере я храню его в переменной $Photo и использую функцию addslashes и file_get_contents
define('DB_HOST','localhost');
define('DB_USER','root');
define('DB_PASS','');
define('DB_NAME','example1');
$conn = new mysqli(DB_HOST, DB_USER, DB_PASS, DB_NAME);
if ($conn ->connect_error){
die ("Conexión fallida: " . $conn->connect_error);
}
$foto = addslashes(file_get_contents($_FILES['photo_user']['tmp_name']));
$query = "INSERT INTO usuario (foto) VALUES ('$foto')";
$result = $conn->query($query);
if(!$result){
die("Query Failed: " . mysqli_error($conn));
}else{
echo "ok";
}
1 answers
В коде, который вы показываете, нет формы, поэтому new FormData(form)
будет генерировать ошибку, и в любом случае, если файл был перетащен, он не добавляется в <input type="file">
, он остается только в переменной file
.
Что вам нужно сделать, это создать пустой объект FormData
и использовать метод . append () для добавления файла, предоставляя 2 параметра: nombre, valor
.
const dropArea = document.querySelector(".drag-area"),
dragText = dropArea.querySelector("header"),
icon = dropArea.querySelector(".icon"),
button = dropArea.querySelector("button"),
input = dropArea.querySelector("input"),
img = dropArea.querySelector(".img"),
enviar = document.querySelector('#enviar');
let file;
button.onclick = () => {
input.click();
};
input.addEventListener("change", function () {
// Esta variable file es donde se almacena el archivo como un objeto
file = this.files[0];
dropArea.classList.add("active");
showFile();
});
dropArea.addEventListener("dragover", (event) => {
event.preventDefault();
dropArea.classList.add("active");
dragText.textContent = "Release to Upload File";
});
dropArea.addEventListener("dragleave", () => {
dropArea.classList.remove("active");
dragText.textContent = "Drag & Drop to Upload File";
});
dropArea.addEventListener("drop", (event) => {
event.preventDefault();
file = event.dataTransfer.files[0];
// Mostrar archivo
showFile();
});
// Esta funcion valida la extension de la imagen y la renderiza para insertarla por pantalla
function showFile() {
let fileType = file.type;
let validExtensions = ["image/jpeg", "image/jpg", "image/png"];
if (validExtensions.includes(fileType)) {
let fileReader = new FileReader();
fileReader.onload = () => {
let fileURL = fileReader.result;
var imgTag = `<img src="${fileURL}" alt="" id="foto">`;
img.innerHTML = imgTag;
dragText.classList.add("none");
button.classList.add("none");
icon.classList.add("none");
};
fileReader.readAsDataURL(file);
} else {
alert("This is not an Image File!");
dropArea.classList.remove("active");
dragText.textContent = "Drag & Drop to Upload File";
}
}
// Aqui hago la peticion fetch
enviar.addEventListener("click", (e) => {
// Evitar comportamiento normal del botón (¿submit?)
e.preventDefault();
// Verificar que se agregó un archivo
if(!file) {
alert('Agrega un archivo');
return;
}
// Crea un objeto FormData
let data = new FormData();
// Agrega el archivo
data.append('photo_user', file);
// Solo para ver que sí se agregó el archivo
console.log(...data);
fetch("enviar.php", {
method: "POST",
body: data,
})
.then((response) => response.text())
.then((response) => {
console.log(response);
});
});
<div class="drag-area">
<div class="icon"><i class="fas fa-cloud-upload-alt"></i></div>
<div class="img"></div>
<header>Drag & Drop to Upload File</header>
<span>OR</span>
<button>Browse File</button>
<input type="file" hidden name="file" />
</div>
<button id="enviar">Enviar</button>
В PHP вы должны сначала переместить загруженный файл из временное расположение к конечному пути с move_uploaded_file () и создать запись только в том случае, если она может быть перемещена.
// Usar una variable para tratar de simplificar
$file = $_FILES['photo_user'];
// Si la propiedad "error" es cero, el archivo se subió correctamente
if($file['error'] == 0) {
// "name" contiene el nombre real del archivo
$foto = $file['name'];
// Mover el archivo a su ubicación final
// Revisa que exista la carpeta y tiene permisos de escritura
if(move_uploaded_file($file['tmp_name'], "ruta/$foto")) {
// Ahora sí puedes insertar en base de datos
} else {
echo 'El archivo se subió, pero no se pudo mover a ubicación final';
}
} else {
echo 'No se pudo subir el archivo';
}
В PHP все еще есть важные вещи, которые вы должны исследовать:
- никогда не доверяйте пользователям, он всегда проверяет, что файл действительно является изображением
- Не используйте
addSlashes()
чтобы избежать переменных, которые вы собираетесь включить в запрос, в зависимости от используемой библиотеки есть параметрыreal_escape_string
- чтобы избежать ошибок e SQL инъекции лучше использовать подготовленные запросы и, таким образом, вы избегаете "изобретать" вещи, как в предыдущем пункте