2016-03-02 197 views
4

美好的一天)我正在構建一個WordPress插件LMS,允許用戶通過AJAX將他們完成的家庭作業文件附加到他們的答案中。一切正常,除了一個場景,當用戶的文件超過允許的最大大小。在這種情況下我的AJAX調用返回的HTML具有以下警告:很好地處理「POST內容 - 字節長度超過了限制」警告

<b>Warning</b>: POST Content-Length of XXXXX bytes exceeds the limit of XXXXX bytes in <b>Unknown</b> on line <b>0</b><br /> 

由於我的腳本的字符串0產生這種警告,它會死,而忽略任何其他指令,留下我這個醜陋的字符串作爲的結果我的電話。 你基本上可以忍受它,因爲最終用戶不會看到它(只是AJAX調用不會有期望的結果),但仍然我想知道是否有機會跳過它並很好地處理它?

好,什麼樣的研究,我已經做了:

  1. 我發現this教程由安德魯Curioso,並設法使從它的東西是這樣的:

    if (isset($_SERVER['CONTENT_LENGTH'])) { 
        if ($_SERVER['CONTENT_LENGTH'] > (substr(ini_get('post_max_size'), -1) * 1024 * 1024)) { 
         echo 'php errors is so much fun'; 
        } 
    } 
    

它沒有提供預期的效果,因爲我的腳本仍然只會從IF語句中回顯附加字符串的正面效果而死亡(此外,如果您嘗試執行類似wp_send_jso n(errorsArray),它不會被執行)。

  1. 使用display_errors,error_reporting關閉顯示錯誤。那麼,這不是我需要的,因爲它仍然不允許我繼續使用腳本並創建自定義錯誤處理程序。什麼樣的建議,我不是在尋找手動編輯max_upload_size,max_post_size等作爲手動編輯服務器上的文件是外掛程式理念

  2. 我WP_DEBUG設置爲FALSE

。無論如何,即使您將最大上傳大小設置爲10GB,只要最終用戶嘗試上傳11GB。我們都知道,這個機制是在成千上萬個網站和應用程序上實現的,我想知道如何最大限度地提高腳本質量,處理這個問題而不會過度使用和損壞用戶體驗。

感謝分享您的想法:)

UPD1 這裏是我的AJAX調用,如果有幫助:

$('#post-assignment-answer').on('click', function (event) { 
    event.preventDefault(); 

    tinymce.triggerSave(); 
    var answerContent = tinymce.get('assignment_user_input_textarea').getContent(); 

    var answerFile = $('#assignment-file-upload')[0].files[0]; 

    var formData = new FormData(); 

    formData.append('action', 'post_assignment_answer'); 
    formData.append('security', lucid_single_assignment_params.post_assignment_answer_nonce); 
    formData.append('post_id', lucid_single_assignment_params.post_id); 
    formData.append('answer_content', answerContent); 
    formData.append('answer_file', answerFile); 

    $.ajax({ 
     url: lucid_single_assignment_params.ajax_url, 
     type: 'post', 
     data: formData, 
     contentType: false, 
     processData: false, 
     success: function (result) { 
      console.log(result); 
     } 
    }); 
}); 

UPD2: 添加了Ajax處理PHP

<?php 

/** 
* Post Assignment Answer 
* 
* @version  1.0.0 
*/ 

if (! defined('ABSPATH')) { 
    exit; 
} // Exit if accessed directly 

// Create AJAX call $result 
$result = array(
    'fileTypeError' => false, 
    'fileSizeError' => false, 
    'uploadError' => false 
); 

// Retrieving current post ID 
$post_id = $_POST['post_id']; 

// Retrieving WYSIWYG content 
$answer_content = ''; 

if (! (trim($_POST['answer_content']) == '')) { 

    $answer_content = wp_kses_post($_POST['answer_content']); 

} 

// Updating WYSIWYG meta field 
update_post_meta($post_id, '_answer_content', $answer_content); 

// Check if user intends to upload a file 
if (!empty($_FILES['answer_file'])) { 

    // Adding timestamp to file name 
    $_FILES['answer_file']['name'] = round(microtime(true)) . '_' . $_FILES['answer_file']['name']; 
    $answer_file = $_FILES['answer_file']; 

    // Setting up uploaded file type validation 
    $supported_types = array(
     'text/plain' // .txt 
    ); 

    $arr_file_type = wp_check_filetype(basename($answer_file['name'])); 

    $uploaded_type = $arr_file_type['type']; 

    // Setting up uploaded file size validation // TODO: This should be optimized 
    $allowed_size = 8388608; 
    $uploaded_size = $answer_file['size']; 

    // Validating, and in a case of success completing upload 
    if (!in_array($uploaded_type, $supported_types)) { 

     $result['fileTypeError'] = __('The type of file you\'ve provided is not allowed', 'lucidlms'); 

    } elseif ($uploaded_size > $allowed_size) { 

     $result['fileSizeError'] = __('The size of file you\'ve provided is exceeding the maximum upload size', 'lucidlms'); 

    } else { 

     /** 
     * Override the default upload path. 
     * 
     * @param array $dir 
     * @return array 
     */ 
     function lucidlms_assignment_upload_dir($dir) { 
      global $user_ID; 

      return array(
       'path' => $dir['basedir'] . '/lucidlms/assignment/user' . $user_ID, 
       'url' => $dir['baseurl'] . '/lucidlms/assignment/user' . $user_ID, 
       'subdir' => '' 
      ) + $dir; 
     } 

     // Register path override 
     add_filter('upload_dir', 'lucidlms_assignment_upload_dir'); 

     $upload = wp_handle_upload($answer_file, array('test_form' => false)); 

     // Set everything back to normal 
     remove_filter('upload_dir', 'lucidlms_user_upload_dir'); 

     if (isset($upload['error']) && $upload['error'] != 0) { 

      $result['uploadError'] = sprintf(__('There was an error uploading your file. The error is: %s', 'lucidlms'), $upload['error']); 

     } else { 

      // Check if there is an old version of file on the server and delete it 
      $existing_answer_file = get_post_meta($post_id, '_answer_file', true); 
      if (! empty($existing_answer_file)) { 

       global $user_ID; 
       $upload_dir = wp_upload_dir(); 
       $existing_answer_file_name = pathinfo($existing_answer_file['file'], PATHINFO_BASENAME); 
       $unlink_path = $upload_dir['basedir'] . '/lucidlms/assignment/user' . $user_ID . '/' . $existing_answer_file_name; 
       unlink($unlink_path); 

      } 

      // Updating post meta 
      update_post_meta($post_id, '_answer_file', $upload); 
     } 
    } 
} 

wp_send_json($result); 
+0

非常方便,謝謝。開始附近有一個小錯誤 - 'substr(ini_get('post_max_size'),-1)'應該是'substr(ini_get('post_max_size'),0,-1)'。 –

回答

5

上傳的圖片的尺寸請務必閱讀和瞭解什麼錯誤消息告訴你:

超過XXXXX字節的限制在未知在線0

正在以0行報告的錯誤,因爲它正在之前拋出你PHP代碼可以執行。所以你不能改變接收PHP腳本中的行爲。

正確的方法是檢查數據的大小BEFORE you upload it(即在Javascript中)。但要注意:

  1. 的Javascript報告單個文件的大小它們編碼前 - Base64編碼增加的開銷約三分之一,再加上其他POST空間屬性值和名字。

  2. 爲post_max_size配置的值是PHP接受的最大值。網絡服務器(例如apache)接受的最大值可能會更低。對於插件來說,或許最合適的解決方案是允許管理員配置上限。

  3. 有人試圖可以很容易地破壞你的安全繞過在Javascript

    任何檢查
+0

我會upvote和除了你的答案,因爲在前端檢查文件大小是唯一的解決方案,我正在考慮作爲適當的一個,只是想確認我在後端完成。謝謝 – markoffden

+1

我不明白爲什麼人們接受建議調整php.ini中的最大限制的答案。這根本不能解決它。因爲這些都可以被超越。說調整post_max_size爲100MB,如果另一個用戶發佈200MB呢?無論限制調整多少,問題總會發生。一個更好的解決方案將首先驗證請求的內容長度,並根據需要繼續執行腳本,例如停止上載或不上載。人們不希望等待上傳200MB數據才能發現它無效。 http://us2.php.net/manual/en/features.file-upload.post-method.php – doncadavona

+0

@doncadavona:「一個更好的解決方案將首先驗證請求的內容長度」 - 你如何建議這樣做當PHP直到文件上傳完成後纔開始執行? – symcbean

0

嘗試此鏈接:http://code.tutsplus.com/tutorials/uploading-files-with-ajax--net-21077

在此上傳。PHP頁面(這是阿賈克斯的,其上傳該文件的主要回調函數),你會得到$_FILES["images"]["size"]

+0

不行,在這種情況下你甚至不會得到$ _POST和$ _FILES的數據,這兩個數組將會是空的 – markoffden

+0

可以ü粘貼代碼,你寫的文件上傳代碼 –

+0

更新爲AJAX調用, t認爲它很重要 – markoffden

相關問題