强制再上传最后分块


某些应用场景下,在分块上传时如果你想强制再上传一次最后的分块,通过落实下面的逻辑便可实现你的需求。

服务端在对文件进行 trim 操作时,将 UploadHandler 类替换为 ChunkedUploadHelper 类,即 new ChunkedUploadHelper(...)。代码其余部分保持不变。 注意:以下代码基于 jQuery FileUpload 5.21 并经过测试

/**
 * Helper method for trimming chunked uploads.
 */
class ChunkedUploadHelper extends UploadHandler {
    /**
     * Custom "get" method to call our custom function.
     */
    public function get($print_response = true) {
        if ($print_response && isset($_GET['download'])) {
            return $this->download();
        }
        $file_name = $this->get_file_name_param();
        if ($file_name) {
            $response = array(
                substr($this->options['param_name'], 0, -1) => $this->get_file_object_trimmed($file_name)
            );
        } else {
            $response = array(
                $this->options['param_name'] => $this->get_file_objects()
            );
        }
        return $this->generate_response($response, $print_response);
    }

    /**
     * Gets a trimmed file object if the maxChunkSize has been given.
     */
    protected function get_file_object_trimmed($file_name) {
        $file_object = $this->get_file_object($file_name);
        if ($file_object != null) {
            // In case an upload was started and we have a max chunk size, trim it to the last full size.
            $max_chunk_size = $_GET['maxChunkSize'] || 0;
            if ($file_object->size > 0) && ($max_chunk_size > 0) {
                $truncated_bytes = floor($file_object->size / $max_chunk_size) * $max_chunk_size;
                if ($truncated_bytes < $file_object->size) {
                    $file_path = $this->get_upload_path($file_name, $this->get_version_param());
                    if (ftruncate(fopen($file_path, 'r+'), $truncated_bytes)) {
                        // Update file size to reflect truncated state
                        $file_object->size = filesize($file_path);
                    } else {
                        // Something went wrong while truncating, redo entire file
                        @unlink($file_path);
                        $file_object = null;
                    }
                }
            }
        }
        return $file_object;
    }
}

然后你需要做的就是将 maxChunkSize 值传递给后端程序,UploadHandler 将负责其余的工作。

$('#fileupload').fileupload({
    /* ... settings as above with add function replaced with ... */
    add: function (e, data) {
        // jQuery Widget Factory uses "namespace-widgetname" since version 1.10.0:
        var fu = $(this).data('blueimp-fileupload') || $(this).data('fileupload');
        var that = this;
        $.getJSON('server/php/', {file: data.files[0].name, maxChunkSize: fu.options.maxChunkSize}, function (result) {
            var file = result.file;
            data.uploadedBytes = file && file.size;
            $.blueimp.fileupload.prototype
                .options.add.call(that, e, data);
        });
    }
});