2011-09-01 76 views
0

早上好。CodeIgniter(和allowed_types)的問題

我正在嘗試與CodeIgniter一起使用Plupload。我在Plupload之前嘗試了uploadify,它的工作很棒,uploadify的主要問題是它從來沒有發送CSRF代碼,無論我使用什麼,這真的很奇怪,所以我回顧了Plupload,並在幾分鐘內按預期工作。但是,它只適用於HTML5上傳器而不適用於Flash上​​傳器。

查看日誌我發現它不工作的原因:使用CodeIgniter文件上傳類時。

由於我正在做一個批量圖像上傳,我設置它允許「JPG,GIF,PNG,JPEG」,但發現上傳拒絕上傳請願,因爲我上傳了一個錯誤的type_file(我發現八位字節/流 - wtf?)。

上傳過程之後,我正在處理圖像(生成大拇指,水印,裁剪等),所以如果我將其設置爲允許所有文件類型,圖像處理將根本不起作用。

我在想什麼就像上傳文件(允許八位字節/流MIME類型)然後將其轉換爲圖像(與imagecreatefromstring和file_get_contents函數),然後單獨處理它。

如果您有任何其他的想法讓我知道

回答

4

去之前,我建議你刪除任何Flash上​​傳,並拿起https://github.com/blueimp/jQuery-File-Upload即始終保持和HTML5是向後兼容的。最多你不會看到上傳欄,但沒有Flash,你不需要對CodeIgniter做任何修改。

以下是不是很精緻。實際上,我在下一個版本的應用程序中放棄了對Flash上​​傳的支持。

通過Flash進行的任何上傳都將作爲應用程序/八位字節流接收到服務器。 這會停止在/application/config/mime.php文件中添加「application/octet-stream」到您感興趣的文件類型中時出現的問題。這裏是an example,請查看文件的底部。

目前,CSRF並不是什麼大問題,因爲Flash擁有自己的Cookie,這意味着它就像一個完全獨立的瀏覽器。甚至在嘗試發送CSRF之前,我們必須將Flash會話ID用於識別您的CodeIgniter。您也將有/application/config/config.php

$config['sess_match_useragent'] = FALSE; 

改變,如果你想使用Uploadify3(這應該Uploadify 2和Plupload工作過),你首先必須添加/應用/庫/ MY_Session.php可以通過POST發送會話數據。

只需使用本文件: https://github.com/woxxy/FoOlSlide/blob/a7522d747fe406da18ce18ae9763f083b89eb91e/application/libraries/MY_Session.php

然後在你的控制器,你必須使人們有可能在任何時間獲取會話ID。

function get_sess_id() 
{ 
    $this->output->set_output(json_encode(array('session' => $this->session->get_js_session(), 'csrf' => $this->security->get_csrf_hash()))); 
} 

您的上傳控制器應該是一個非常標準的上傳功能。確保您在上傳時使用了正確的名稱(「userfile」)。

現在,最糟糕的部分:視圖文件。我可能已經刪除了一些細節,但我認爲一些額外的數據可以幫助您編碼,而不必在Uploadify3中查找太多。現在

<script type="text/javascript"> 
    function updateSession() 
    { 
     jQuery.post('<?php echo site_url('/admin/series/get_sess_id'); ?>', 
     function(result){ 

      jQuery('#file_upload_flash').uploadifySettings('postData', { 
       'ci_sessionz' : result.session, 
       '<?php echo $this->security->get_csrf_token_name(); ?>' : result.csrf, 
       'chapter_id' : <?php echo $chapter->id; ?> 
      }, false); 
      setTimeout('updateSession()', 6000); 
     }, 'json'); 
    } 

    jQuery(document).ready(function() { 
     jQuery('#file_upload_flash').uploadify({ 
      'swf' : '<?php echo site_url(); ?>assets/uploadify/uploadify.swf', 
      'uploader' : '<?php echo site_url('/admin/series/upload/compressed_chapter'); ?>', 
      'cancelImage' : '<?php echo site_url(); ?>assets/uploadify/uploadify-cancel.png', 
      'checkExisting' : false, 
      'preventCaching' : false, 
      'multi' : true, 
      'buttonText' : '<?php echo _('Use flash upload'); ?>', 
      'width': 200, 
      'auto'  : true, 
      'requeueErrors' : true, 
      'uploaderType' : 'flash', 
      'postData' : {}, 
      'onSWFReady' : function() { 
       updateSession(); 
      }, 
      'onUploadSuccess' : function(file, data, response) { 
       var files = jQuery.parseJSON(data); 
       var fu = jQuery('#fileupload').data('fileupload'); 
       fu._adjustMaxNumberOfFiles(-files.length); 
       fu._renderDownload(files) 
       .appendTo(jQuery('#fileupload .files')) 
       .fadeIn(function() { 
        jQuery(this).show(); 
       }); 
      } 
     }); 
    }); 

</script> 
<div id="file_upload_flash"></div> 

,如果它是不是已經足夠的工作......有一個在Uploadify3的錯誤,不讓它觸發一個或兩個回調。

下面的代碼的固定版本:https://github.com/woxxy/FoOlSlide/blob/a7522d747fe406da18ce18ae9763f083b89eb91e/assets/uploadify/jquery.uploadify.js

您可能要來縮小它。

但是如果你想使用jQuery-File-Upload?

然後你所要做的就是調整你的控制器。這裏有一個例子(我不會通過清潔這段代碼要麼,因爲它很可能只是做一個破碎的上傳控制器反正)

function upload() 
{ 
    $info = array(); 

    // compatibility for flash uploader and browser not supporting multiple upload 
    if (is_array($_FILES['Filedata']) && !is_array($_FILES['Filedata']['tmp_name'])) 
    { 
     $_FILES['Filedata']['tmp_name'] = array($_FILES['Filedata']['tmp_name']); 
     $_FILES['Filedata']['name'] = array($_FILES['Filedata']['name']); 
    } 

    for ($file = 0; $file < count($_FILES['Filedata']['tmp_name']); $file++) 
    { 
     $valid = explode('|', 'png|zip|rar|gif|jpg|jpeg'); 
     if (!in_array(strtolower(substr($_FILES['Filedata']['name'][$file], -3)), $valid)) 
      continue; 

     if (!in_array(strtolower(substr($_FILES['Filedata']['name'][$file], -3)), array('zip', 'rar'))) 
      $pages = $this->files_model->page($_FILES['Filedata']['tmp_name'][$file], $_FILES['Filedata']['name'][$file], $this->input->post('chapter_id')); 
     else 
      $pages = $this->files_model->compressed_chapter($_FILES['Filedata']['tmp_name'][$file], $_FILES['Filedata']['name'][$file], $this->input->post('chapter_id')); 

     foreach ($pages as $page) 
     { 
      $info[] = array(
       'name' => $page->filename, 
       'size' => $page->size, 
       'url' => $page->page_url(), 
       'thumbnail_url' => $page->page_url(TRUE), 
       'delete_url' => site_url("admin/series/delete/page"), 
       'delete_data' => $page->id, 
       'delete_type' => 'POST' 
      ); 
     } 
    } 

    // return a json array 
    echo json_encode($info); 
    return true; 
} 


function get_file_objects() 
{ 
    // Generate JSON File Output (Required by jQuery File Upload) 
    header('Content-type: application/json'); 
    header('Pragma: no-cache'); 
    header('Cache-Control: private, no-cache'); 
    header('Content-Disposition: inline; filename="files.json"'); 

    $id = $this->input->post('id'); 
    $chapter = new Chapter($id); 
    $pages = $chapter->get_pages(); 
    $info = array(); 
    foreach ($pages as $page) 
    { 
     $info[] = array(
      'name' => $page['filename'], 
      'size' => intval($page['size']), 
      'url' => $page['url'], 
      'thumbnail_url' => $page['thumb_url'], 
      'delete_url' => site_url("admin/series/delete/page"), 
      'delete_data' => $page['id'], 
      'delete_type' => 'POST' 
     ); 
    } 

    echo json_encode($info); 
    return true; 
} 

更增添了巨大的視圖代碼(這時候它幾乎是股票一個來自jQuery的上傳)

<div id="fileupload"> 
    <link href="<?php echo site_url(); ?>assets/jquery-file-upload/jquery-ui.css" rel="stylesheet" id="theme" /> 
    <link href="<?php echo site_url(); ?>assets/jquery-file-upload/jquery.fileupload-ui.css" rel="stylesheet" /> 
    <?php echo form_open_multipart(""); ?> 
    <div class="fileupload-buttonbar"> 
     <label class="fileinput-button"> 
      <span>Add files...</span> 
      <input type="file" name="Filedata[]" multiple> 
     </label> 
     <button type="submit" class="start">Start upload</button> 
     <button type="reset" class="cancel">Cancel upload</button> 
     <button type="button" class="delete">Delete files</button> 
    </div> 
    <?php echo form_close(); ?> 
    <div class="fileupload-content"> 
     <table class="files"></table> 
     <div class="fileupload-progressbar"></div> 
    </div> 
</div> 
<script id="template-upload" type="text/x-jquery-tmpl"> 
    <tr class="template-upload{{if error}} ui-state-error{{/if}}"> 
     <td class="preview"></td> 
     <td class="name">${name}</td> 
     <td class="size">${sizef}</td> 
     {{if error}} 
     <td class="error" colspan="2">Error: 
      {{if error === 'maxFileSize'}}File is too big 
      {{else error === 'minFileSize'}}File is too small 
      {{else error === 'acceptFileTypes'}}Filetype not allowed 
      {{else error === 'maxNumberOfFiles'}}Max number of files exceeded 
      {{else}}${error} 
      {{/if}} 
     </td> 
     {{else}} 
     <td class="progress"><div></div></td> 
     <td class="start"><button>Start</button></td> 
     {{/if}} 
     <td class="cancel"><button>Cancel</button></td> 
    </tr> 
</script> 
<script id="template-download" type="text/x-jquery-tmpl"> 
    <tr class="template-download{{if error}} ui-state-error{{/if}}"> 
     {{if error}} 
     <td></td> 
     <td class="name">${name}</td> 
     <td class="size">${sizef}</td> 
     <td class="error" colspan="2">Error: 
      {{if error === 1}}File exceeds upload_max_filesize (php.ini directive) 
      {{else error === 2}}File exceeds MAX_FILE_SIZE (HTML form directive) 
      {{else error === 3}}File was only partially uploaded 
      {{else error === 4}}No File was uploaded 
      {{else error === 5}}Missing a temporary folder 
      {{else error === 6}}Failed to write file to disk 
      {{else error === 7}}File upload stopped by extension 
      {{else error === 'maxFileSize'}}File is too big 
      {{else error === 'minFileSize'}}File is too small 
      {{else error === 'acceptFileTypes'}}Filetype not allowed 
      {{else error === 'maxNumberOfFiles'}}Max number of files exceeded 
      {{else error === 'uploadedBytes'}}Uploaded bytes exceed file size 
      {{else error === 'emptyResult'}}Empty file upload result 
      {{else}}${error} 
      {{/if}} 
     </td> 
     {{else}} 
     <td class="preview"> 
      {{if thumbnail_url}} 
      <a href="${url}" target="_blank"><img src="${thumbnail_url}"></a> 
      {{/if}} 
     </td> 
     <td class="name"> 
      <a href="${url}"{{if thumbnail_url}} target="_blank"{{/if}}>${name}</a> 
     </td> 
     <td class="size">${sizef}</td> 
     <td colspan="2"></td> 
     {{/if}} 
     <td class="delete"> 
      <button data-type="${delete_type}" data-url="${delete_url}" data-id="${delete_data}">Delete</button> 
     </td> 
    </tr> 
</script> 
<script src="<?php echo site_url(); ?>assets/js/jquery-ui.js"></script> 
<script src="<?php echo site_url(); ?>assets/js/jquery.tmpl.js"></script> 
<script src="<?php echo site_url(); ?>assets/jquery-file-upload/jquery.fileupload.js"></script> 
<script src="<?php echo site_url(); ?>assets/jquery-file-upload/jquery.fileupload-ui.js"></script> 
<script src="<?php echo site_url(); ?>assets/jquery-file-upload/jquery.iframe-transport.js"></script> 

<script type="text/javascript"> 

    jQuery(function() { 
     jQuery('#fileupload').fileupload({ 
      url: '<?php echo site_url('/admin/series/upload/compressed_chapter'); ?>', 
      sequentialUploads: true, 
      formData: [ 
       { 
        name: 'chapter_id', 
        value: <?php echo $chapter->id; ?> 
       } 
      ] 
     }); 

     jQuery.post('<?php echo site_url('/admin/series/get_file_objects'); ?>', { id : <?php echo $chapter->id; ?> }, function (files) { 
      var fu = jQuery('#fileupload').data('fileupload'); 
      fu._adjustMaxNumberOfFiles(-files.length); 
      fu._renderDownload(files) 
      .appendTo(jQuery('#fileupload .files')) 
      .fadeIn(function() { 
       jQuery(this).show(); 
      }); 

     }); 

     jQuery('#fileupload .files a:not([target^=_blank])').live('click', function (e) { 
      e.preventDefault(); 
      jQuery('<iframe style="display:none;"></iframe>') 
      .prop('src', this.href) 
      .appendTo('body'); 
     }); 

    }); 

</script> 
+0

出色答卷,很詳細,現在我更清楚地瞭解所有這一切背後的問題。 我明顯喜歡HTML5上傳器,但在某些情況下(舊瀏覽器),我需要Flash支持。 試圖使用Uploadify 3,但它甚至不啓動上傳器。我會再試一次,讓你知道。 – demogar