Загрузка фрагмента файла HTML JS PHP

Я работаю с решением для фрагментации файлов (не могу вспомнить, где я его нашел), но я изменил решение в соответствии со своими потребностями. Проблема в том, что хотя в большинстве случаев файл загружается успешно, иногда я получаю сообщение об ошибке

Uncaught SyntaxError: Unexpected token < in JSON at position 0

Я также получаю другую ошибку в то же время

( unlink(test/H2jig-6.png): Resource temporarily unavailable in ... )

Я надеялся, что вы, ребята, сможете обнаружить проблему в моем коде, которая вызывает эту проблему. Я думаю, что ему удается отсоединить файлы слишком рано, прежде чем загрузка будет завершена, а затем он не может их найти.

Загрузить файл HTML/JS

<!DOCTYPE HTML>
<html lang = "en-US">
<head>
  <meta charset = "UTF-8">
  <title>test upload by chunk</title>
</head>
<body>
  <input type = "file" id = "f" />

  <script>
  function makeid() {
  var text = "";
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

  for (var i = 0; i < 5; i++)
    text += possible.charAt(Math.floor(Math.random() * possible.length));

  return text;
}


  (function() {

var f = document.getElementById('f');

if (f.files.length)
processFile();

f.addEventListener('change', processFile, false);


function processFile(e) {
var scount = 0;
var file = f.files[0];
console.info(file);
var ext =  file.name.split('.').pop();
ext = '.'+ext;
var size = file.size;

var sliceSize = 250000;
var num_of_slices = Math.ceil(size / sliceSize);
var fileid = makeid();
var start = 0;

setTimeout(loop, 1);

function loop() {
  var end = start + sliceSize;

  if (size - end < 0) {
    end = size;
  }

  var s = slice(file, start, end);
  scount ++;
  send(s, start, end,scount,size,num_of_slices,ext,fileid);

  if (end < size) {
    start += sliceSize;
    setTimeout(loop, 1);
  }
}
}


function send(piece, start, end,scount,size,num_of_slices,ext,fileid) {
var formdata = new FormData();
var xhr = new XMLHttpRequest();

xhr.open('POST', 'uploadchunk2.php', true);

formdata.append('start', start);
formdata.append('end', end);
formdata.append('file', piece);
formdata.append('scount', scount);
formdata.append('fsize', size);
formdata.append('num_of_slices', num_of_slices);
formdata.append('ext', ext);
formdata.append('fileid', fileid);
xhr.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
        var myArr = JSON.parse(this.responseText);
        console.info(myArr);
        // myFunction(myArr);
    }
};
xhr.send(formdata);
}

/**
* Formalize file.slice
*/

function slice(file, start, end) {
var slice = file.mozSlice ? file.mozSlice :
            file.webkitSlice ? file.webkitSlice :
            file.slice ? file.slice : noop;

return slice.bind(file)(start, end);
}

function noop() {

}


})();


  </script>
</body>
</html>

Загрузка PHP

<?php


$target_path = '/test/';

$tmp_name = $_FILES['file']['tmp_name'];
$filename = $_FILES['file']['name'];
$target_file = $target_path.$filename;
$num_chunks_uploaded = $_POST['scount'];
$num_chunks_created = $_POST['num_of_slices'];
$extension = $_POST['ext'];
$file_id = $_POST['fileid'];
$file_location = 'test/';
$file_path = $file_location.$file_id.$extension;
$chunked_file_path = $file_location.$file_id.'-'.$num_chunks_uploaded.$extension;
move_uploaded_file(
    $_FILES['file']['tmp_name'],
    $chunked_file_path
);




// count amount of uploaded chunks
$chunksUploaded = 0;
for ($i=1; $i <= $num_chunks_created ; $i++) {
  if ( file_exists($file_location.$file_id.'-'.$i.$extension) ) {
       ++$chunksUploaded;
  }
}



// when this triggers - that means the chunks are uploaded
if ($chunksUploaded == $num_chunks_created) {

    /* here you can reassemble chunks together */
    for ($i = 1; $i <= $num_chunks_created; $i++) {

      $file = fopen($file_location.$file_id.'-'.$i.$extension, 'rb');
      $buff = fread($file, 2097152);
      fclose($file);

      $final = fopen($file_path, 'ab');
      $write = fwrite($final, $buff);
      fclose($final);

      unlink($file_location.$file_id.'-'.$i.$extension);
    }
}

$data = $chunksUploaded;
header('Content-Type: application/json');
echo json_encode($_POST);









 ?>

Вы должны обернуть это в try/catch: JSON.parse(this.responseText) и записать текст ответа и ошибку в блоке catch. Вероятно, вы увидите, что получаете HTML (с дополнительной информацией о том, что пошло не так) вместо ожидаемого JSON. Кроме того, возможно, измените заголовок вашего вопроса и тому подобное, чтобы отразить фактический вопрос, и оставьте теги в соответствующем месте.

Charlie Schliesser 01.02.2019 17:37
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
1
758
1

Ответы 1

Это не ответ на вашу проблему, но он решает одну проблему, которая у вас есть в вашем JavaScript.

PHP требует, чтобы поле MAX_FILE_SIZE было отправлено с загруженными файлами. Это поле должно стоять перед полем файла в переменных POST. Итак, вам нужно добавить:

formdata.append('MAX_FILE_SIZE', 1000000) // or whatever you want the max size to be

перед полем, содержащим файл для отправки.

Спасибо, я добавлю это в код, но мне все еще нужно выяснить, почему некоторые из загрузок терпят неудачу.

PleaseHelpTheNoob 02.02.2019 22:11

Я инкапсулирую механизм загрузки файлов PHP в класс, который выполняет все проверки ошибок, проверку типов MIME и другие проверки, предоставляемые PHP для обеспечения безопасности. Вы просто создаете экземпляр объекта Uploader с путем сохранения и разрешенными типами файлов, а затем передаете файл POST методу uploadFile(). Показанный пример использования покажет вам, что именно пошло не так на стороне PHP, вызвав исключение. pastebin.com/MbbCm0uS

Diggy Dude 04.02.2019 18:53

Вы можете закомментировать вызов rename() в строке 53. Я переименовываю загруженные файлы в их хэш MD5, чтобы предотвратить конфликт имен файлов, и использую базу данных для управления ими, но это может быть нежелательно в вашем приложении.

Diggy Dude 04.02.2019 18:59

Спасибо за этого чувака.

PleaseHelpTheNoob 04.02.2019 23:24

Другие вопросы по теме