Pracuję nad generatywnym projektem artystycznym, w którym chciałbym umożliwić użytkownikom zapisywanie powstałych obrazów z algorytmu. Ogólna idea to:
- Utwórz obraz na kanwie HTML5 przy użyciu algorytmu generatywnego
- Po ukończeniu obrazu zezwól użytkownikom na zapisanie płótna jako pliku obrazu na serwerze
- Pozwól użytkownikowi pobrać obraz lub dodać go do galerii sztuk wyprodukowanych przy użyciu algorytmu.
Utknąłem jednak na drugim etapie. Po pomocy Google znalazłem ten post na blogu , który wydawał się być dokładnie tym, czego chciałem:
Co doprowadziło do kodu JavaScript:
function saveImage() {
var canvasData = canvas.toDataURL("image/png");
var ajax = new XMLHttpRequest();
ajax.open("POST", "testSave.php", false);
ajax.onreadystatechange = function() {
console.log(ajax.responseText);
}
ajax.setRequestHeader("Content-Type", "application/upload");
ajax.send("imgData=" + canvasData);
}
i odpowiedni PHP (testSave.php):
<?php
if (isset($GLOBALS["HTTP_RAW_POST_DATA"])) {
$imageData = $GLOBALS['HTTP_RAW_POST_DATA'];
$filteredData = substr($imageData, strpos($imageData, ",") + 1);
$unencodedData = base64_decode($filteredData);
$fp = fopen('/path/to/file.png', 'wb');
fwrite($fp, $unencodedData);
fclose($fp);
}
?>
Ale to wydaje się w ogóle nic nie robić.
Więcej Googling pokazuje ten post na blogu, który jest oparty na poprzednim samouczku. Nie bardzo różne, ale być może warte spróbowania:
$data = $_POST['imgData'];
$file = "/path/to/file.png";
$uri = substr($data,strpos($data, ",") + 1);
file_put_contents($file, base64_decode($uri));
echo $file;
Ten tworzy plik (tak), ale jest uszkodzony i wydaje się, że nic nie zawiera. Wygląda również na pusty (rozmiar pliku 0).
Czy jest coś naprawdę oczywistego, że robię źle? Ścieżka, w której przechowuję mój plik, jest zapisywalna, więc to nie jest problem, ale wydaje się, że nic się nie dzieje i nie jestem pewien, jak to debugować.
Edytować
Po linku Salvidora Dali zmieniłem żądanie AJAX na:
function saveImage() {
var canvasData = canvas.toDataURL("image/png");
var xmlHttpReq = false;
if (window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
}
else if (window.ActiveXObject) {
ajax = new ActiveXObject("Microsoft.XMLHTTP");
}
ajax.open("POST", "testSave.php", false);
ajax.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
ajax.onreadystatechange = function() {
console.log(ajax.responseText);
}
ajax.send("imgData=" + canvasData);
}
A teraz plik obrazu został utworzony i nie jest pusty! Wygląda na to, że typ zawartości ma znaczenie i że zmiana go w celu x-www-form-urlencoded
umożliwienia wysłania danych obrazu.
Konsola zwraca (raczej duży) ciąg kodu base64, a plik danych ma wielkość ~ 140 kB. Jednak nadal nie mogę go otworzyć i wydaje się, że nie jest sformatowany jako obraz.
$data
w drugim kodzie php), wszystko, co otrzymuję, to pusta linia. Dlaczego miałoby to być? Wydaje się, że być może przesyłane dane nie są poprawne, ale wydaje się, że przesyłam je tak, jak pokazują to przykłady ...
DataUriUpload
komponentem. Jest to udokumentowane tutaj i zawiera kilka dodatkowych środków sprawdzania poprawności i egzekwowania bezpieczeństwa.
ajax.send(canvasData );
którego korzystasz, korzysta z niego podczas korzystania z niegoajax.send("imgData="+canvasData);
. Dlatego$GLOBALS["HTTP_RAW_POST_DATA"]
nie będzie to, czego oczekujesz, prawdopodobnie powinieneś użyć$_POST['imgData']
.