You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:25:22