У меня странная проблема с системой, которую я создаю. Я пытаюсь создать систему для загрузки файлов на сервер. У меня нет прав на прямую запись в файл и HTTP POST multipart/form-data
загрузка файлов не работает. У меня к сожалению нет прямого доступа к серверу.
Мое решение состоит в том, чтобы использовать JQuery’s $.ajax
функция, чтобы загрузить файл через HTTP PUT, затем прочитать его из STDIN в PHP на сервере, и загрузить содержимое в другое место через FTP.
Кажется, все работает, но где-то вдоль линии добавляются дополнительные байты. На клиенте Windows утверждает, что файл (я тестирую с моего сайта favicon.ico
файл) составляет 7358 байт. Когда я читаю файл, используя стандартный объект Javascript FileReader, он выглядит как 7311 байт. Затем я успешно помещаю его в сценарий PHP на сервере, который утверждает, что он прочитал 10890 байт, с чем FileZilla соглашается, когда я проверяю папку дампа по FTP.
Вот мой код Javascript для загрузки (jQuery 1.11.3 включен, и file_input
является <input type="file" id="file_input"/>
:
function upload(){
console.log("upload");
var f = file_input.files[0];
var r = new FileReader();
r.onload = function(event){
var d = r.result;
console.log("data loaded");
console.log(d.length);
$.ajax({
url: "upload.php?name="+encodeURIComponent(f.name)+"&mime="+encodeURIComponent(f.mime),
context: document.body,
method: "PUT",
contentType: "application/octet-stream",
data: d
}).done(function(data){
console.log("done");
console.log(data);
});
};
r.onerror = function(event){
alert("ERROR READING FILE!\nCode " + event.target.error.code);
};
r.readAsText(f);
console.log("initiated");
}
Как видите, имя и тип MIME включены через строку запроса GET.
Вот мой PHP, который принимает загрузку (часть upload.php):
if(strtoupper($_SERVER['REQUEST_METHOD'])=="PUT"){
echo "uploading\n";
echo "connected\n";
var_dump($_POST);
echo "x";
$file=fopen("php://input","r");
var_dump($file);
$x="";
while($byte=fgetc($file)!==false){
$x.=$byte;
}
echo strlen($x);
echo "\n";
$ftp=fopen('ftp://user:[email protected]/admin/fs/upload/'.uniqid('',true),'w');
var_dump($ftp);
fwrite($ftp,$x);
fclose($ftp);
echo "done\n";
}
Я проверил файлы в блокноте, и большая часть файла оказалась неизменной (не было никаких HTTP-заголовков или чего-либо еще), однако новый файл отказывался открываться в любой программе просмотра изображений (оригинал должен был). Исходя из различий в файлах — только некоторые части являются изменениями, и они заменяются на то, что кажется случайными невизуальными символами — я предполагаю, что это как-то связано с несоответствием кодировки символов. Любые идеи были бы хорошы.
Спасибо,
MagikM18
РЕДАКТИРОВАТЬ
Мой сервер Apache / 2.4.6 и работает на x86_64-redhat-linux-gnu (согласно phpinfo ()).
Кроме того, я протестировал его с помощью текстового файла (сценарий PHP), и он работал просто отлично — это должно быть как-то связано с двоичным содержимым файла.
Для бинарных файлов (т.е. не текстовых) вы можете попробовать добавить b
под флаги fopen
:
fopen("php://input","rb");
/*
...
*/
$ftp=fopen('ftp://user:[email protected]/admin/fs/upload/'.uniqid('',true),'wb');
Вы также должны отправлять файлы как двоичные файлы, в дополнение к получению потока. Смотрите ссылку в комментариях.
Других решений пока нет …