Codeigniter 3.1.6无法上传PNG格式图片问题求助
解决CodeIgniter 3.1.6 + Dropzone.js PNG上传失败的问题
看起来你遇到了一个很常见的上传坑——JPG能传但PNG不行,我来帮你一步步排查解决:
第一步:先加错误调试,搞清楚到底哪里出问题
你的控制器代码现在完全没有错误处理,根本不知道PNG上传失败的具体原因。先修改控制器,加上错误输出,这样能直接看到问题所在:
function addimg() { // 返回JSON格式的响应,方便Dropzone接收 header('Content-Type: application/json'); $response = ['status' => 'error', 'message' => '']; if (!empty($_FILES)) { $tempFile = $_FILES['file']['tmp_name']; $targetPath = './assets/img/'; $targetFile = $targetPath . $_FILES['file']['name']; // 先确保目标目录存在,没有的话创建 if (!is_dir($targetPath)) { mkdir($targetPath, 0755, true); } // 检查PHP上传是否有错误 if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) { $response['message'] = '上传错误码: ' . $_FILES['file']['error']; echo json_encode($response); return; } // 尝试移动文件并捕获错误 if (move_uploaded_file($tempFile, $targetFile)) { $response['status'] = 'success'; $response['message'] = '文件上传成功'; } else { $response['message'] = '移动文件失败: ' . error_get_last()['message']; } } else { $response['message'] = '没有接收到上传文件'; } echo json_encode($response); }
修改后重新测试PNG上传,打开浏览器控制台的网络面板,查看请求的响应,就能看到具体错误了。
第二步:检查CodeIgniter的CSRF保护(最可能的原因)
CodeIgniter默认开启了CSRF保护,而Dropzone的AJAX上传请求默认不会携带CSRF令牌,这会导致CI直接拒绝请求——这也是为什么部分文件能传、部分不能传的常见原因(比如缓存、令牌有效期等)。
你需要在Dropzone的配置里加上CSRF令牌,两种方式二选一:
方式1:通过请求头传递
<form action="admin/addimg" enctype="multipart/form-data" class="dropzone" style="margin-bottom: 5%; border: 2px dashed #0087F7; border-radius: 5px; background: white;" id="imgupld"></form> <script> Dropzone.options.imgupld = { paramName: "file", maxFilesize: 20, // MB acceptedFiles: "image/*", // Accept images only dictDefaultMessage: "Drag your image here", // 添加CSRF令牌到请求头 headers: { 'X-CSRF-Token': '<?php echo $this->security->get_csrf_hash(); ?>' } }; </script>
方式2:通过POST参数传递
<form action="admin/addimg" enctype="multipart/form-data" class="dropzone" style="margin-bottom: 5%; border: 2px dashed #0087F7; border-radius: 5px; background: white;" id="imgupld"></form> <script> Dropzone.options.imgupld = { paramName: "file", maxFilesize: 20, // MB acceptedFiles: "image/*", // Accept images only dictDefaultMessage: "Drag your image here", // 在发送请求时附加CSRF参数 sending: function(file, xhr, formData) { formData.append('<?php echo $this->security->get_csrf_token_name(); ?>', '<?php echo $this->security->get_csrf_hash(); ?>'); } }; </script>
第三步:改用CodeIgniter上传类(更可靠)
直接用原生PHP的move_uploaded_file虽然简单,但CI的上传类已经帮你处理了文件类型校验、权限、错误处理等问题,更符合CI的开发规范,也能避免很多坑:
function addimg() { header('Content-Type: application/json'); $response = ['status' => 'error', 'message' => '']; // 配置上传参数 $config['upload_path'] = './assets/img/'; $config['allowed_types'] = 'gif|jpg|jpeg|png'; // 明确允许的图片类型 $config['max_size'] = 20480; // 20MB(注意单位是KB) $config['file_name'] = $_FILES['file']['name']; // 保留原文件名 // 加载上传类 $this->load->library('upload', $config); // 执行上传 if (!$this->upload->do_upload('file')) { // 上传失败,返回错误信息 $response['message'] = $this->upload->display_errors('', ''); } else { // 上传成功,返回结果 $response['status'] = 'success'; $response['message'] = '文件上传成功'; $response['file_info'] = $this->upload->data(); } echo json_encode($response); }
第四步:检查服务器端的其他可能问题
如果上面的步骤都没解决,再排查这几个点:
- 目录权限:确保
./assets/img/目录的权限是755(所有者可读写执行,其他可读执行),如果是Linux服务器,还要确保目录的所有者是Web服务器用户(比如www-data)。 - GD扩展支持:运行
phpinfo()查看GD扩展的配置,确认是否支持PNG(一般都支持,但不排除特殊环境)。 - MIME类型设置:确保服务器识别
image/png为合法的图片MIME类型,部分服务器可能会对PNG的MIME类型做限制。
内容的提问来源于stack exchange,提问作者blur
相关产品推荐
相关产品推荐

