如何在Dropzone显示现有文件 - CodeIgniter 4(详细教程)

332 阅读2分钟

Dropzone在文件上传后显示预览,但缩略图在页面重新加载后被删除。

要重新创建缩略图需要在Dropzone初始化时发送AJAX请求。

在本教程中,我展示了如何在CodeIgniter 4的Dropzone容器中显示现有文件。

How to Display existing files in Dropzone - CodeIgniter 4

演示 下载

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() 方法添加缩略图。
  • 使用Dropzonesending 事件发送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加载现有文件。