Dropzone JS с колбой: параллельная загрузка по частям - PullRequest
0 голосов
/ 14 июня 2019

Я пытаюсь использовать Dropzone JS с колбой в качестве бэкэнда. Конфигурация Dropzone:

<form method="POST" action='/process_chunk' class="dropzone dz-clickable"
     id="dropper" enctype="multipart/form-data">
</form>

<script type="application/javascript">
   Dropzone.options.dropper = {
       {# https://gitlab.com/meno/dropzone/wikis/faq#chunked-uploads #}
       paramName: 'file',
       acceptedFiles: '.csv',
       chunking: true,
       forceChunking: true,
       chunkSize: 100000, // bytes
       parallelChunkUploads: true,
       maxFilesize: 1025, // megabytes
</script>

и мой фляжка выглядит следующим образом

@app.route('/process_chunk', methods=['POST'])
def process_chunk():
    current_chunk = int(request.form['dzchunkindex'])

    file = request.files['file']
    save_path = os.path.join(app.config['DATA_DIR'], file.filename)

    try:
        with open(save_path, 'ab+') as f:
            # Goto the offset, aka after the chunks we already wrote
            f.seek(int(request.form['dzchunkbyteoffset']))
            f.write(file.stream.read())
    except OSError:
        # log.exception will include the traceback so we can see what's wrong
        log.exception('Could not write to file')
        return make_response(("Couldn't write the file to disk", 500))

    total_chunks = int(request.form['dztotalchunkcount'])

    if current_chunk + 1 == total_chunks:
        # This was the last chunk, the file should be complete and the size we expect
        if os.path.getsize(save_path) != int(request.form['dztotalfilesize']):
            log.error(f"File {file.filename} was completed, "
                      f"but has a size mismatch."
                      f"Was {os.path.getsize(save_path)} but we"
                      f" expected {request.form['dztotalfilesize']} ")
            return make_response(('Size mismatch', 500))
        else:
            log.info(f'File {file.filename} has been uploaded successfully')
    else:
        log.debug(f'Chunk {current_chunk + 1} of {total_chunks} '
                  f'for file {file.filename} complete')

    return make_response(("Chunk upload successful", 200))

Это прекрасно работает, если я установил parallelChunkUploads в false. Куски загружаются по одному, и в результате файл выглядит нормально. Например, я использую небольшой файл (409 байт) и устанавливаю размер фрагмента равным 50 байтам:

serial chunk upload.

Файл результата выглядит точно как входной файл. Когда для parallelChunkUploads установлено значение true, загрузка фрагментов выполняется параллельно:

parallel chunk upload

но файл результатов полностью перепутан:

оригинальный файл

cod,char,xx
01,aaaa,xx
02,bbbb,xx
03,cccc,xx
04,dddd,xx
05,eeee,xx
06,ffff,xx
07,gggg,xx
08,iiii,xx
09,kkkk,xx
10,llll,xx
11,mmmm,xx
12,gerf,xx
13,flrg,xx
14,erge,xx
15,lkro,xx
16,ergf,xx
17,kiwu,xx
18,erjg,xx
19,hytj,xx
20,utkj,xx
21,rger,xx
22,ehth,xx
23,kmik,xx
24,ergb,xx
25,ergk,xx
26,egeg,xx
27,ejer,xx
28,gtrh,xx
29,thrh,xx
30,rhtr,xx
31,gtrh,xx
32,thrh,xx
33,rhtr,xx

загруженный файл

cod,char,xx
01,aaaa,xx
02,bbbb,xx
03,cccc,xx
0iiii,xx
09,kkkk,xx
10,llll,xx
11,mmmm,xx
12,gerf,xx
13,flrg,xx
14,erge,xx
15,lkro,xx
16,ergf4,dddd,xx
05,eeee,xx
06,ffff,xx
07,gggg,xx
08,x
21,rger,xx
22,ehth,xx
23,kmik,xx
24,ergb,xx
,xx
17,kiwu,xx
18,erjg,xx
19,hytj,xx
20,utkj,x9,thrh,xx
30,rhtr,xx
31,gtrh,xx
32,thrh,xx
33,rhtr,xx

25,ergk,xx
26,egeg,xx
27,ejer,xx
28,gtrh,xx
2

Последний блок красного цвета, потому что front получает ответ 'Size mismatch', 500, потому что размер файла после загрузки последнего блока отличается. У вас есть идеи, как это исправить?

...