Dropzone在文件上传后显示预览,但缩略图在页面重新加载后被删除。
要重新创建缩略图需要在Dropzone初始化时发送AJAX请求。
在本教程中,我展示了如何在CodeIgniter 4的Dropzone容器中显示现有文件。
1.启 用CSRF
- 打开
.env文件。 - 从
security.tokenName,security.headerName,security.cookieName,security.expires, 和security.regenerate的开头删除#。 - 使用
security.tokenName读取CSRF哈希值,你可以用任何其他值来更新它:
# security.csrfProtection = 'cookie'
# security.tokenRandomize = false
security.tokenName = 'csrf_token_name'
security.headerName = 'X-CSRF-TOKEN'
security.cookieName = 'csrf_cookie_name'
security.expires = 7200
security.regenerate = true
# security.redirect = true
# security.samesite = 'Lax'
- 打开
app/Config/Filters.php文件。 - 取消
'csrf'中的注释,如果有注释的话,在'before':
public $globals = [
'before' => [
// 'honeypot',
'csrf',
// 'invalidchars',
],
'after' => [
'toolbar',
// 'honeypot',
// 'secureheaders',
],
];
2.路 线
- 打开
app/Config/Routes.php文件: - 定义2个路由 -
- / -显示文件上传视图
- page/readFiles -读取现有文件
- page/fileUpload -用来上传文件
完成的代码
$routes->get('/', 'PageController::index');
$routes->get('page/readFiles', 'PageController::readFiles');
$routes->post('page/fileUpload', 'PageController::fileUpload');
3.控 制器
- 创建
PageController控制器。
php spark make:controller PageController
- 打开
app/Controllers/PageController.php文件 - 创建2个方法
- index() -加载索引视图。
- readFiles() -这个方法用来读取现有的文件以显示在Dropzone中。
在$validextension_arr 数组中分配有效的文件扩展名。从uploads 文件夹中读取文件并检查文件扩展名是否存在于$validextension_arr 数组中。如果它存在,那么用名称、文件大小和路径初始化$file_list 数组。
以JSON格式返回$file_list 数组。
-
- fileUpload() -该方法用于上传Dropzone的选定文件。
定义文件的验证。我把最大的文件大小设置为2MB(2048 Kb)。
如果文件没有被验证,那么把0 赋给$data['success'] ,把验证响应赋给$data['error'] 。
如果文件验证成功,则将文件上传到"uploads" 位置。将1 赋给$data['success'] ,将Uploaded Successfully! 赋给$data['message'] 。
以JSON格式返回$data 数组。
完成的代码
<?php
namespace App\Controllers;
class PageController extends BaseController{
public function index(){
return view('index');
}
// Read files
public function readFiles(){
$file_list = array();
$validextension_arr = array('jpeg','jpg','png','pdf');
// Target location
$target_dir = "uploads/";
$dir = $target_dir;
if (is_dir($dir)){
if ($dh = opendir($dir)){
// Read files
while (($file = readdir($dh)) !== false){
if($file != '' && $file != '.' && $file != '..'){
// File path
$file_path = $target_dir.$file;
// Check if it is folder or not
if(!is_dir($file_path)){
$size = filesize($file_path);
$extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));
if (in_array($extension,$validextension_arr)) {
$file_list[] = array('name'=>$file,'size'=>$size,'path'=>$file_path);
}
}
}
}
closedir($dh);
}
}
return $this->response->setJSON($file_list);
}
// Upload file
public function fileUpload(){
$data = array();
// Read new token and assign to $data['token']
$data['token'] = csrf_hash();
## Validation
$validation = \Config\Services::validation();
$input = $validation->setRules([
'file' => 'uploaded[file]|max_size[file,2048]|ext_in[file,jpeg,jpg,png,pdf],'
]);
if ($validation->withRequest($this->request)->run() == FALSE){
$data['success'] = 0;
$data['error'] = $validation->getError('file');// Error response
}else{
if($file = $this->request->getFile('file')) {
if ($file->isValid() && ! $file->hasMoved()) {
// Get file name and extension
$name = $file->getName();
$ext = $file->getClientExtension();
// Get random file name
$newName = $file->getRandomName();
// Store file in public/uploads/ folder
$file->move('../public/uploads', $newName);
// Response
$data['success'] = 1;
$data['message'] = 'Uploaded Successfully!';
}else{
// Response
$data['success'] = 2;
$data['message'] = 'File not uploaded.';
}
}else{
// Response
$data['success'] = 2;
$data['message'] = 'File not uploaded.';
}
}
return $this->response->setJSON($data);
}
}
4.查 看
在app/Views/ 中创建index.php 文件。
包括Dropzone和jQuery库。
<link rel="stylesheet" href="https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" type="text/css" />
<script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>
创建一个隐藏的元素,在name 属性中存储在.env 文件中指定的CSRF令牌名称,在value 属性中存储CSRF哈希。
<input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />
创建<form action="<?=site_url('page/fileUpload')?>", class='dropzone' ></form> 来初始化Dropzone。
脚本
- 禁用Dropzone autoDiscover -
Dropzone.autoDiscover = false并在class="dropzone"上初始化Dropzone。 - 设置最大上传文件大小为2MB和有效文件扩展名 - ".jpeg, .jpg, .png, .pdf"。
- 使用
init,使用jQuery AJAX加载现有文件。在成功回调的情况下,对响应进行循环,并将{ name: value.name, size: value.size }归入mockFile。 - 使用
emit()方法添加缩略图。 - 使用Dropzone
sending事件发送CSRF令牌 -formData.append(csrfName, csrfHash);。 - 使用
success事件更新令牌哈希,并检查返回响应。 - 如果
response.status == 0表示有一个错误,如果response.status == 2表示文件没有被上传。使用alert()显示错误信息。
完成的代码
<!doctype html>
<html>
<head>
<title>How to Display existing file in Dropzone - CodeIgniter 4</title>
<!-- CSS -->
<link rel="stylesheet" href="https://unpkg.com/dropzone@5/dist/min/dropzone.min.css" type="text/css" />
<!-- Script -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://unpkg.com/dropzone@5/dist/min/dropzone.min.js"></script>
<style type="text/css">
.dz-preview .dz-image img{
width: 100% !important;
height: 100% !important;
object-fit: cover;
}
</style>
</head>
<body>
<!-- CSRF token -->
<input type="hidden" class="txt_csrfname" name="<?= csrf_token() ?>" value="<?= csrf_hash() ?>" />
<div class='content'>
<!-- Dropzone -->
<form action="<?=site_url('page/fileUpload')?>", class='dropzone' ></form>
</div>
<!-- Script -->
<script>
Dropzone.autoDiscover = false;
var myDropzone = new Dropzone(".dropzone",{
maxFilesize: 2, // 2 mb
acceptedFiles: ".jpeg,.jpg,.png,.pdf",
init: function() {
myDropzone = this;
$.ajax({
url: '<?=site_url('page/readFiles')?>',
type: 'get',
dataType: 'json',
success: function(response){
$.each(response, function(key,value) {
var mockFile = { name: value.name, size: value.size };
myDropzone.emit("addedfile", mockFile);
myDropzone.emit("thumbnail", mockFile, value.path);
myDropzone.emit("complete", mockFile);
});
}
});
}
});
myDropzone.on("sending", function(file, xhr, formData) {
// CSRF Hash
var csrfName = $('.txt_csrfname').attr('name'); // CSRF Token name
var csrfHash = $('.txt_csrfname').val(); // CSRF hash
formData.append(csrfName, csrfHash);
});
myDropzone.on("success", function(file, response) {
$('.txt_csrfname').val(response.token);
if(response.success == 0){ // Error
alert(response.error);
}
if(response.success == 2){
alert(response.message);
}
});
</script>
</body>
</html>
5.运 行
- 使用命令提示符(如果你在Windows上)或终端(如果你在Mac或Linux上)导航到该项目,并
- 执行 "php spark serve "命令。
php spark serve
- 在网络浏览器中运行
http://localhost:8080。
6.演 示
7.总 结
在Dropzone初始化时使用init 选项,你可以在Dropzone容器中使用jQuery AJAX加载现有文件。