Codeigniter 3中Dropzone Ajax上传报错:未选择上传文件
问题描述
在CodeIgniter 3框架中使用Dropzone组件通过Ajax上传文件时,弹出错误提示:"You did not select a file to upload"。
以下是我用到的视图、JavaScript及控制器代码:
视图代码
<form> <h1>图片上传</h1> <!-- Bootstrap资源文件 --> <link rel="stylesheet" href="<?php echo base_url('assets/source_files/bootstrap.min.css');?>" > <!-- Dropzone资源文件 --> <link rel="stylesheet" href="<?php echo base_url('assets/source_files/dropzone.min.css');?>" > <label class="form_lable">选择图片 </label> <div class="dropzone-container col-md-6" id="demo-dropzone" > <div class="dz-default dz-message" > <div class="dz-icon"> <i class="demo-pli-upload-to-cloud icon-5x"></i> </div> <div> <span class="dz-text">Drop files to upload</span> <p class="text-sm text-muted">or click to pick manually</p> </div> </div> <div class="fallback"> <input type="file" name="userfile" id="userfile" /> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="submit_btn">提交</button> </div> </form>
JavaScript代码
$('#demo-dropzone').dropzone({ url:"", autoProcessQueue: false, addRemoveLinks: true, multiple:false, uploadMultiple:true, // 单次请求上传多个文件 parallelUploads: 1, maxFiles: 1, maxFilesize: 500, acceptedFiles: ".jpg, .png, .jpeg", init: function() { var myDropzone = this; myDropzone.on('maxfilesexceeded', function(file) { this.removeAllFiles(); this.addFile(file); }); this.on("removedfile", function(file) { }); // 更新选择器以匹配你的按钮 $("#submit_btn").click(function(e) { e.preventDefault(); myDropzone.processQueue(); }); this.on("successmultiple", function(file, response) { if (response && file) { console.log(response); } }); } });
控制器代码
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Image_upload extends CI_Controller { public function index(){ $this->load->view('image_send'); } // 文件上传函数 public function do_upload(){ $image_name = $_FILES['file']['name'][0]; $target= $_FILES['file']['tmp_name'][0]; $target_file = basename($image_name); $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION)); $custom_file=basename(uniqid().'.'.$imageFileType); if(is_dir('upload_image')){ echo "目录已存在"; } else{ mkdir('upload_image'); } $config['upload_path'] = 'upload_image/'; $config['allowed_types'] = 'gif|jpg|png|jpeg'; $config['file_name'] = $image_name; $this->upload->initialize($config); $this->load->library('upload',$config); if ($this->upload->do_upload('userfile')) { $data = array('upload_data' => $this->upload->data()); print_r($data); } else { $error = array('error' => $this->upload->display_errors()); print_r($error); } } } ?>
问题原因及修复方案
1. Dropzone未指定上传URL
当前JS配置里url:""是空的,Dropzone不知道要把文件提交到哪里,必须补充CI控制器的上传方法路径:url: "<?php echo base_url('image_upload/do_upload'); ?>"
2. 文件字段名称不匹配
Dropzone默认用file作为上传字段名,但你在CI控制器里调用do_upload('userfile'),两者不一致。需要在Dropzone配置里添加paramName: "userfile",统一字段名。
3. 上传模式冲突
你同时设置了multiple:false(单文件选择)和uploadMultiple:true(多文件批量上传),逻辑矛盾。既然你限制了maxFiles:1,直接把uploadMultiple改成false,同时把successmultiple事件换成success事件。
4. CI上传库初始化顺序错误
你先调用initialize再加载库,这会导致配置不生效。正确做法是加载库时直接传入配置,或者先加载库再初始化。
5. 直接操作$_FILES存在风险
不要直接取$_FILES['file']['name'][0],因为字段名已经改成userfile,而且单文件上传不需要取数组下标。
修改后的完整代码
修改后的JavaScript
$('#demo-dropzone').dropzone({ url: "<?php echo base_url('image_upload/do_upload'); ?>", // 指定上传地址 autoProcessQueue: false, addRemoveLinks: true, multiple: false, uploadMultiple: false, // 关闭多文件上传 parallelUploads: 1, maxFiles: 1, maxFilesize: 500, acceptedFiles: ".jpg, .png, .jpeg", paramName: "userfile", // 和CI上传字段名统一 init: function() { var myDropzone = this; myDropzone.on('maxfilesexceeded', function(file) { this.removeAllFiles(); this.addFile(file); }); this.on("removedfile", function(file) { // 可添加文件移除后的清理逻辑 }); $("#submit_btn").click(function(e) { e.preventDefault(); myDropzone.processQueue(); }); this.on("success", function(file, response) { // 单文件用success事件 if (response && file) { console.log(response); } }); } });
修改后的控制器
<?php defined('BASEPATH') OR exit('No direct script access allowed'); class Image_upload extends CI_Controller { public function index(){ $this->load->view('image_send'); } // 文件上传函数 public function do_upload(){ // 先检查是否有文件上传 if (empty($_FILES['userfile']['name'])) { echo json_encode(['error' => '未选择上传文件']); return; } $image_name = $_FILES['userfile']['name']; $imageFileType = strtolower(pathinfo($image_name, PATHINFO_EXTENSION)); $custom_file = uniqid() . '.' . $imageFileType; // 生成唯一文件名避免覆盖 // 确保上传目录存在,添加权限和递归创建 $upload_path = 'upload_image/'; if (!is_dir($upload_path)) { mkdir($upload_path, 0755, true); } $config['upload_path'] = $upload_path; $config['allowed_types'] = 'gif|jpg|png|jpeg'; $config['file_name'] = $custom_file; $this->load->library('upload', $config); // 加载库时传入配置 if ($this->upload->do_upload('userfile')) { $data = array('upload_data' => $this->upload->data()); echo json_encode($data); // 返回JSON格式便于前端处理 } else { $error = array('error' => $this->upload->display_errors()); echo json_encode($error); } } } ?>
优化后的视图(补充Dropzone JS文件)
<form> <h1>图片上传</h1> <!-- Bootstrap资源文件 --> <link rel="stylesheet" href="<?php echo base_url('assets/source_files/bootstrap.min.css');?>" > <!-- Dropzone资源文件 --> <link rel="stylesheet" href="<?php echo base_url('assets/source_files/dropzone.min.css');?>" > <script src="<?php echo base_url('assets/source_files/dropzone.min.js');?>"></script> <!-- 补充JS文件 --> <label class="form_label">选择图片 </label> <div class="dropzone-container col-md-6" id="demo-dropzone"> <div class="dz-default dz-message" > <div class="dz-icon"> <i class="demo-pli-upload-to-cloud icon-5x"></i> </div> <div> <span class="dz-text">Drop files to upload</span> <p class="text-sm text-muted">or click to pick manually</p> </div> </div> <div class="fallback"> <input type="file" name="userfile" id="userfile" /> </div> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">关闭</button> <button type="button" class="btn btn-primary" id="submit_btn">提交</button> </div> </form>
内容的提问来源于stack exchange,提问作者Amara Khan
相关产品推荐
相关产品推荐

