无法在 CodeIgniter 中使用拖放区上传大 zip 文件
Cannot upload big zip files using drop-zone in CodeIgniter
我正在尝试使用拖放区上传 zip 文件。上传小型 zip 文件就好了。但是,超过 5MB 的 zip 不能上传。不知何故,上传过程卡在 100% 并保持在那里,直到手动刷新页面。
你可以在这里看到:
拖动文件后,在 100% 时卡住并在控制台中出现错误。
错误:
HTML
<?php $exts = str_replace('"', '', $this->product_settings->digital_allowed_file_extensions);
$exts = str_replace(',', ", ", $exts);
$exts = strtoupper($exts); ?>
<div class="form-box">
<div class="form-box-head">
<h4 class="title">
<?php echo trans('digital_files'); ?>
<small><?php echo trans("allowed_file_extensions"); ?>: <strong class="font-500"><?php echo $exts; ?></strong></small>
</h4>
</div>
<div class="form-box-body">
<div class="row">
<div class="col-sm-12">
<div id="digital_files_upload_result" class="row-custom">
<?php $this->load->view('dashboard/product/_digital_files_upload_response'); ?>
</div>
<div class="error-message error-message-file-upload"></div>
</div>
</div>
</div>
</div>
<!-- File item template -->
<script type="text/html" id="files-template-digital-files">
<li class="media">
<div class="media-body">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</li>
</script>
JS:我在这里使用的库:https://github.com/danielm/uploader
<script>
$('#drag-and-drop-zone-digital-files').dmUploader({
url: '<?php echo base_url(); ?>upload-digital-files-post',
queue: true,
extFilter: [<?php echo $this->product_settings->digital_allowed_file_extensions;?>],
multiple: false,
extraData: function (id) {
return {
"product_id": <?php echo $product->id; ?>,
"<?php echo $this->security->get_csrf_token_name(); ?>": $.cookie(csfr_cookie_name)
};
},
onDragEnter: function () {
this.addClass('active');
},
onDragLeave: function () {
this.removeClass('active');
},
onNewFile: function (id, file) {
ui_multi_add_file(id, file, "digital-files");
},
onBeforeUpload: function (id) {
ui_multi_update_file_progress(id, 0, '', true);
ui_multi_update_file_status(id, 'uploading', 'Uploading...');
},
onUploadProgress: function (id, percent) {
ui_multi_update_file_progress(id, percent);
},
onUploadSuccess: function (id, data) {
var obj = JSON.parse(data);
if (obj.result == 1) {
document.getElementById("digital_files_upload_result").innerHTML = obj.html_content;
}
},
onFileExtError: function (file) {
$(".error-message-file-upload").html("<?php echo trans('invalid_file_type'); ?>");
setTimeout(function () {
$(".error-message-file-upload").empty();
}, 4000);
},
});
$(document).ajaxStop(function () {
$('#drag-and-drop-zone-digital-files').dmUploader({
url: '<?php echo base_url(); ?>upload-digital-files-post',
queue: true,
extFilter: [<?php echo $this->product_settings->digital_allowed_file_extensions;?>],
multiple: false,
extraData: function (id) {
return {
"product_id": <?php echo $product->id; ?>,
"<?php echo $this->security->get_csrf_token_name(); ?>": $.cookie(csfr_cookie_name)
};
},
onDragEnter: function () {
this.addClass('active');
},
onDragLeave: function () {
this.removeClass('active');
},
onNewFile: function (id, file) {
ui_multi_add_file(id, file, "digital-files");
},
onBeforeUpload: function (id) {
ui_multi_update_file_progress(id, 0, '', true);
ui_multi_update_file_status(id, 'uploading', 'Uploading...');
},
onUploadProgress: function (id, percent) {
ui_multi_update_file_progress(id, percent);
},
onUploadSuccess: function (id, data) {
var obj = JSON.parse(data);
if (obj.result == 1) {
document.getElementById("digital_files_upload_result").innerHTML = obj.html_content;
}
},
onFileExtError: function (file) {
$(".error-message-file-upload").html("<?php echo trans('invalid_file_type'); ?>");
setTimeout(function () {
$(".error-message-file-upload").empty();
}, 4000);
},
});
});
</script>
PHP
//upload digital files
public function upload_digital_files($product_id)
{
if (isset($_FILES['file'])) {
if (empty($_FILES['file']['name'])) {
exit();
}
}
$product = $this->product_model->get_product_by_id($product_id);
if (!empty($product)) {
$ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
$file_name = str_slug($this->general_settings->application_name) . "-digital-file-" . $product->id . uniqid() . "." . $ext;
$this->load->model('upload_model');
if ($this->upload_model->digital_file_upload('file', $file_name)) {
$data = array(
'product_id' => $product_id,
'user_id' => user()->id,
'file_name' => $file_name,
'storage' => 'local',
'created_at' => date('Y-m-d H:i:s')
);
@$this->db->close();
@$this->db->initialize();
$this->db->insert('digital_files', $data);
}
}
}
//digital file upload
public function digital_file_upload($input_name, $file_name)
{
$config['upload_path'] = './uploads/digital-files/';
$config['allowed_types'] = '*';
$config['file_name'] = $file_name;
$this->load->library('upload', $config);
if ($this->upload->do_upload($input_name)) {
$data = array('upload_data' => $this->upload->data());
if (isset($data['upload_data']['full_path'])) {
return true;
}
return null;
} else {
return null;
}
}
首先你的代码错误不明确。您可以在调用 JSON.parse 之前打印变量数据,如下所示,以便显示原始错误。
onUploadSuccess: function (id, data) {
console.log(data);
},
我认为您在 return 结果之前没有在 Codeigniter 中将 content-type header 设置为 JSON。
只需要在PHP文件中加入如下代码试试
$this->response->setContentType('Content-Type: application/json');
文件上传成功后 return 响应
return json_encode(['status'=>'ok','path'=>'file-path']);
如果它不起作用,请先尝试此包中提供的演示代码。
https://github.com/danielm/uploader/tree/master/demo
这个问题的答案在这里。
我将服务器限制更改为这种方式,现在运行良好。
memory_limit = 250M //The maximum amount of memory in bytes a script is allowed to allocate.
max_input_time = 600 //The maximum time in seconds a script is allowed to parse input data.
max_execution_time = 600 //The maximum time in seconds a script is allowed to run before it is terminated.
post_max_size = 200M //The maximum size in bytes of data that can be posted with the POST method. Typically, should be larger than upload_max_filesize and smaller than memory_limit.
upload_max_filesize = 100M //The maximum size in bytes of an uploaded file.
我正在尝试使用拖放区上传 zip 文件。上传小型 zip 文件就好了。但是,超过 5MB 的 zip 不能上传。不知何故,上传过程卡在 100% 并保持在那里,直到手动刷新页面。
你可以在这里看到:
拖动文件后,在 100% 时卡住并在控制台中出现错误。
错误:
HTML
<?php $exts = str_replace('"', '', $this->product_settings->digital_allowed_file_extensions);
$exts = str_replace(',', ", ", $exts);
$exts = strtoupper($exts); ?>
<div class="form-box">
<div class="form-box-head">
<h4 class="title">
<?php echo trans('digital_files'); ?>
<small><?php echo trans("allowed_file_extensions"); ?>: <strong class="font-500"><?php echo $exts; ?></strong></small>
</h4>
</div>
<div class="form-box-body">
<div class="row">
<div class="col-sm-12">
<div id="digital_files_upload_result" class="row-custom">
<?php $this->load->view('dashboard/product/_digital_files_upload_response'); ?>
</div>
<div class="error-message error-message-file-upload"></div>
</div>
</div>
</div>
</div>
<!-- File item template -->
<script type="text/html" id="files-template-digital-files">
<li class="media">
<div class="media-body">
<div class="progress">
<div class="progress-bar" role="progressbar" style="width: 0%" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
</li>
</script>
JS:我在这里使用的库:https://github.com/danielm/uploader
<script>
$('#drag-and-drop-zone-digital-files').dmUploader({
url: '<?php echo base_url(); ?>upload-digital-files-post',
queue: true,
extFilter: [<?php echo $this->product_settings->digital_allowed_file_extensions;?>],
multiple: false,
extraData: function (id) {
return {
"product_id": <?php echo $product->id; ?>,
"<?php echo $this->security->get_csrf_token_name(); ?>": $.cookie(csfr_cookie_name)
};
},
onDragEnter: function () {
this.addClass('active');
},
onDragLeave: function () {
this.removeClass('active');
},
onNewFile: function (id, file) {
ui_multi_add_file(id, file, "digital-files");
},
onBeforeUpload: function (id) {
ui_multi_update_file_progress(id, 0, '', true);
ui_multi_update_file_status(id, 'uploading', 'Uploading...');
},
onUploadProgress: function (id, percent) {
ui_multi_update_file_progress(id, percent);
},
onUploadSuccess: function (id, data) {
var obj = JSON.parse(data);
if (obj.result == 1) {
document.getElementById("digital_files_upload_result").innerHTML = obj.html_content;
}
},
onFileExtError: function (file) {
$(".error-message-file-upload").html("<?php echo trans('invalid_file_type'); ?>");
setTimeout(function () {
$(".error-message-file-upload").empty();
}, 4000);
},
});
$(document).ajaxStop(function () {
$('#drag-and-drop-zone-digital-files').dmUploader({
url: '<?php echo base_url(); ?>upload-digital-files-post',
queue: true,
extFilter: [<?php echo $this->product_settings->digital_allowed_file_extensions;?>],
multiple: false,
extraData: function (id) {
return {
"product_id": <?php echo $product->id; ?>,
"<?php echo $this->security->get_csrf_token_name(); ?>": $.cookie(csfr_cookie_name)
};
},
onDragEnter: function () {
this.addClass('active');
},
onDragLeave: function () {
this.removeClass('active');
},
onNewFile: function (id, file) {
ui_multi_add_file(id, file, "digital-files");
},
onBeforeUpload: function (id) {
ui_multi_update_file_progress(id, 0, '', true);
ui_multi_update_file_status(id, 'uploading', 'Uploading...');
},
onUploadProgress: function (id, percent) {
ui_multi_update_file_progress(id, percent);
},
onUploadSuccess: function (id, data) {
var obj = JSON.parse(data);
if (obj.result == 1) {
document.getElementById("digital_files_upload_result").innerHTML = obj.html_content;
}
},
onFileExtError: function (file) {
$(".error-message-file-upload").html("<?php echo trans('invalid_file_type'); ?>");
setTimeout(function () {
$(".error-message-file-upload").empty();
}, 4000);
},
});
});
</script>
PHP
//upload digital files
public function upload_digital_files($product_id)
{
if (isset($_FILES['file'])) {
if (empty($_FILES['file']['name'])) {
exit();
}
}
$product = $this->product_model->get_product_by_id($product_id);
if (!empty($product)) {
$ext = pathinfo($_FILES['file']['name'], PATHINFO_EXTENSION);
$file_name = str_slug($this->general_settings->application_name) . "-digital-file-" . $product->id . uniqid() . "." . $ext;
$this->load->model('upload_model');
if ($this->upload_model->digital_file_upload('file', $file_name)) {
$data = array(
'product_id' => $product_id,
'user_id' => user()->id,
'file_name' => $file_name,
'storage' => 'local',
'created_at' => date('Y-m-d H:i:s')
);
@$this->db->close();
@$this->db->initialize();
$this->db->insert('digital_files', $data);
}
}
}
//digital file upload
public function digital_file_upload($input_name, $file_name)
{
$config['upload_path'] = './uploads/digital-files/';
$config['allowed_types'] = '*';
$config['file_name'] = $file_name;
$this->load->library('upload', $config);
if ($this->upload->do_upload($input_name)) {
$data = array('upload_data' => $this->upload->data());
if (isset($data['upload_data']['full_path'])) {
return true;
}
return null;
} else {
return null;
}
}
首先你的代码错误不明确。您可以在调用 JSON.parse 之前打印变量数据,如下所示,以便显示原始错误。
onUploadSuccess: function (id, data) {
console.log(data);
},
我认为您在 return 结果之前没有在 Codeigniter 中将 content-type header 设置为 JSON。
只需要在PHP文件中加入如下代码试试
$this->response->setContentType('Content-Type: application/json');
文件上传成功后 return 响应
return json_encode(['status'=>'ok','path'=>'file-path']);
如果它不起作用,请先尝试此包中提供的演示代码。 https://github.com/danielm/uploader/tree/master/demo
这个问题的答案在这里。 我将服务器限制更改为这种方式,现在运行良好。
memory_limit = 250M //The maximum amount of memory in bytes a script is allowed to allocate.
max_input_time = 600 //The maximum time in seconds a script is allowed to parse input data.
max_execution_time = 600 //The maximum time in seconds a script is allowed to run before it is terminated.
post_max_size = 200M //The maximum size in bytes of data that can be posted with the POST method. Typically, should be larger than upload_max_filesize and smaller than memory_limit.
upload_max_filesize = 100M //The maximum size in bytes of an uploaded file.