[英]What MIMEType should I use for .dat files in react dropzone?
[英]dropzone chunk uploading: what callbacks should I use to call ajax and process files/chunks?
我正在尝试使用dropzone js和php正确实现块上传。 我主要关心的是:我应该在哪里进行ajax调用? 通常(没有任何块),您只需指定URL参数。 但是,对于块来说,这还不够,我想,因为将只有1个ajax调用,但是理想情况下,块将是几个,我们必须等待全部,然后再用php重新组装整个文件。 因此,以您的经验,执行ajax调用或在哪里调用的正确位置是什么? (也许这是只打一个电话的方法吗?)。 这是我当前代码的简单摘录:
window['dropzone' + panel_index] = new Dropzone(
selector,
{
url: ajax_url + '?action=uploadfile'
,addRemoveLinks: true
,maxFiles: 5
,maxFilesize: maxfilesize
,uploadMultiple:false
,parallelUploads: 1
,chunking:true
,forceChunking:true
,chunkSize:10485760 // 10Mb
,retryChunks: true // retry chunks on failure
,retryChunksLimit: 3
,chunksUploaded:function(file, done){
// called only once, when chunks are finished > do something ajax > php to reassemble the file?
done();
}
,params: function(file, xhr, chunk){
// called once per every chunk > do something ajax > php?
if(chunk){
$.extend(true, p, {
dzuuid: chunk.file.upload.uuid,
dzchunkindex: chunk.index,
dztotalfilesize: chunk.file.size,
dzchunksize: this.options.chunkSize,
dztotalchunkcount: chunk.file.upload.totalChunkCount,
dzchunkbyteoffset: chunk.index * this.options.chunkSize
});
}
return p;
}// params
,init: function(){
this.on('success', function(newfile){
// called after chunksUploaded > do something ajax > php?
});// onsuccess
this.on('uploadprogress', function(file, progress, bytesent){
// called continuously
})
}// dropzone init option
}// dropzone options
);
简而言之,服务端块处理所需的唯一回调是传递给params
的函数。 像这样(从我的代码中提取):
,params: function(files, xhr, chunk){
var p = { // $_POST
app_type: 'configurator'
,app_code: manager.code
,file_types: filetypes
,max_filesize: maxfilesize
,upf: upf
}
if(chunk){
$.extend(true, p, {
dzuuid: chunk.file.upload.uuid,
dzchunkindex: chunk.index,
dztotalfilesize: chunk.file.size,
dzchunksize: this.options.chunkSize,
dztotalchunkcount: chunk.file.upload.totalChunkCount,
dzchunkbyteoffset: chunk.index * this.options.chunkSize
});
}
return p;
}// params
所调用的url只是一般dropzone的url参数。 每个块调用一次。
在php中,您可以使用$ _POST ['dzchunkindex']保存修改后名称的块,例如。
// do all the sanitisation tasks, then:
$target_chunk = $this->target_path . DS . $filename . $chunk_index;
// and then do the file saving tasks
在处理完所有块之后,您将拥有与服务器上的块一样多的文件。 然后,在同一函数上,检查块索引是否类似于dztotalchunkcount - 1
(在其他情况下,如果当前块是最后一个),并且在这种情况下,还将所有块合并到一个文件中。 例:
if($chunk_index == $total_chunks - 1){
$final = fopen($target_file, 'wb'); // Open for write and start from beginning of file
for ($i = 0; $i < $total_chunks; $i++) {
$file = fopen($target_file.$i, 'rb');
while($buff = fread($file, 4096)){ fwrite($final, $buff); }
fclose($file);
unlink($target_file.$i);
}
fclose($final);
}
我是在chunksUploaded
选项中做的。 悬浮窗上传所有块中对我来说,我执行内的另一个Ajax调用chunksUploaded
从我上传的是串接所有上传的文件到一个单独的PHP脚本。
因此,每个块上传都调用在PHP中上传块的相同Dropzone网址:
<?php
/* ========================================
VARIABLES
======================================== */
// chunk variables
$fileId = $_POST['dzuuid'];
$chunkIndex = $_POST['dzchunkindex'] + 1;
$chunkTotal = $_POST['dztotalchunkcount'];
// file path variables
$ds = DIRECTORY_SEPARATOR;
$targetPath = dirname( __FILE__ ) . "{$ds}uploads{$ds}";
$fileType = strtolower(pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION));
$fileSize = $_FILES["file"]["size"];
$filename = "{$fileId}-{$chunkIndex}.{$fileType}";
$targetFile = $targetPath . $filename;
/* ========================================
DEPENDENCY FUNCTIONS
======================================== */
$returnResponse = function ($info = null, $filelink = null, $status = "error") {
die (json_encode( array(
"status" => $status,
"info" => $info,
"file_link" => $filelink
)));
};
/* ========================================
VALIDATION CHECKS
======================================== */
// I deleted a bunch of validation that goes here to keep the code short
/* ========================================
CHUNK UPLOAD
======================================== */
move_uploaded_file($_FILES['file']['tmp_name'], $targetFile);
// Be sure that the file has been uploaded
if ( !file_exists($targetFile) ) $returnResponse("An error occurred and we couldn't upload the requested file.");
chmod($targetFile, 0777) or $returnResponse("Could not reset permissions on uploaded chunk.");
$returnResponse(null, null, "success");
然后,chunksUploaded对串联php脚本执行另一个ajax调用(注意,我如何使用拖放区上载ID作为序列来标识哪些文件块属于一起):
<?php
// get variables
$fileId = $_GET['dzuuid'];
$chunkTotal = $_GET['dztotalchunkcount'];
// file path variables
$ds = DIRECTORY_SEPARATOR;
$targetPath = dirname( __FILE__ ) . "{$ds}uploads{$ds}";
//$fileType = strtolower(pathinfo($_GET['fileName'], PATHINFO_EXTENSION));
$fileType = $_GET['fileName'];
/* ========================================
DEPENDENCY FUNCTIONS
======================================== */
$returnResponse = function ($info = null, $filelink = null, $status = "error") {
die (json_encode( array(
"status" => $status,
"info" => $info,
"file_link" => $filelink
)));
};
/* ========================================
CONCATENATE UPLOADED FILES
======================================== */
// loop through temp files and grab the content
for ($i = 1; $i <= $chunkTotal; $i++) {
// target temp file
$temp_file_path = realpath("{$targetPath}{$fileId}-{$i}.{$fileType}") or $returnResponse("Your chunk was lost mid-upload.");
// copy chunk
$chunk = file_get_contents($temp_file_path);
if ( empty($chunk) ) $returnResponse("Chunks are uploading as empty strings.");
// add chunk to main file
file_put_contents("{$targetPath}{$fileId}.{$fileType}", $chunk, FILE_APPEND | LOCK_EX);
// delete chunk
unlink($temp_file_path);
if ( file_exists($temp_file_path) ) $returnResponse("Your temp files could not be deleted.");
}
// and by the time you get here you should have your concatenated file in the "uploads" folder to do with what you want
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.