За последние 24 часа нас посетили 30368 программистов и 1753 робота. Сейчас ищут 850 программистов ...

Вывод ошибок сервера через AJAX

Тема в разделе "PHP для новичков", создана пользователем smartCreate, 17 янв 2017.

  1. smartCreate

    smartCreate Новичок

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4
    Добрый день! Проблема следующая - осуществляю загрузку изображений на сайте пользователем. Само собой для загружаемого элемента существуют некоторые ограничения - расширение файла, вес, размер. Хочу сделать что бы посетитель видел отчет по каждой из причин если они возникли, то есть "Недопустимый тип"файла, "Превышен максимальный размер" и т.д.

    Форма выглядит таким образом:
    HTML:
    1.  
    2. <form id="feeds" method="post" action="<?php echo base_url(); ?>feeds/add_feeds" enctype="multipart/form-data">
    3.     <input type="text" placeholder="Заголовок статьи" name="title" />
    4.     <input type="text" placeholder="Ключ статьи" name="key_n" />
    5.     <textarea placeholder="Текс статьи" name="txt" rows="10"></textarea>
    6.     <input type="file" name="userfile" />
    7.     <button type="submit" class="button--8">ОПУБЛИКОВАТЬ</button>
    8. </form>
    9.  
    Сервер:
    PHP:
    1. function add_feeds() {
    2.     $config['upload_path'] = './library/img/news/';
    3.     $config['allowed_types'] = 'gif|jpg|png|jpeg';
    4.     $config['max_size']    = '100';
    5.     $config['max_width']  = '1024';
    6.     $config['max_height']  = '768';
    7.     $config['encrypt_name']    = TRUE;
    8.     $config['remove_spaces'] = TRUE;
    9.     $this->load->library('upload', $config);
    10.  
    11.     if ( ! $this->upload->do_upload()){
    12.         $error = array('error' => $this->upload->display_errors());
    13.         $this->load->view('pages/feeds/index', $error);
    14.     }else{
    15.         $image_data = $this->upload->data();
    16.          
    17.         $feeds['title']  = $_POST['title'];
    18.         $feeds['txt'] = $_POST['txt'];
    19.         $feeds['key_n'] = $_POST['key_n'];
    20.         $feeds['img'] = $image_data['file_name'];
    21.         $this->main_model->new_feeds($feeds);
    22.                 echo json_encode($feeds);
    23.     }
    24. }
    Сервер написан на php-фреймворке Codignaiter, обработка и отображение ошибок происходит вот в этой части кода:
    PHP:
    1. if ( ! $this->upload->do_upload()){
    2.     $error = array('error' => $this->upload->display_errors());
    3.     $this->load->view('pages/feeds/index', $error);
    4. }
    Для того что бы ошибка отображалась на страницу добавляю вот это:
    PHP:
    1. <?php if (isset($error)) {?>
    2.     <?php echo $error;?>
    3. <?php }?>
    И если на форму не вешать аякс, что бы отправка на сервер происходила обновлением страницы, то вывод ошибок будет работать, а вот если повесить аякс, то нет...
    Конечно, в скрипте можно вывести какой-то allert с ошибкой типа "Что-то пошло не так", но это не совсем то что я хочу, обработчтк выглядит так:
    Код (Javascript):
    1. $("form#feeds").submit(function(e){
    2.     e.preventDefault();
    3.     var f = this,
    4.         form = new FormData(this),
    5.         s = $(f.elements).last(),
    6.         e = s.end().slice(0, -2).removeClass('input-error').filter(function() {
    7.             return !$.trim(this.value)
    8.         });
    9.     if(e.length) e.addClass('input-error');
    10.     else {
    11.         s.prop('disabled', 1);
    12.         s.end().not(s);
    13.         $.ajax({
    14.             url: f.action,
    15.             type: 'POST',
    16.             data: form,
    17.             contentType: false,
    18.             processData: false,
    19.             cache: false,
    20.             dataType: 'json',
    21.             success: function(data) {
    22.                 f.reset();
    23.                 s.prop('disabled', 0);
    24.                 e.removeClass('input-error');
    25.                 $("#content").load("feeds #content");
    26.             },
    27.             error: function() {
    28.                 // здесь вывести ошибку
    29.             }
    30.         });
    31.     }
    32. });
    Я догадываюсь что мне каким-то образом нужно вывести вот это:
    PHP:
    1. <?php if (isset($error)) {?>
    2.     <?php echo $error;?>
    3. <?php }?>
    здесь:
    Код (Javascript):
    1. error: function() {
    2.         // здесь вывести ошибку
    3. }
    Но, как это сделать я не понимаю, и не могу найти адекватного ответа в интернете, прошу помочь, словом или делом))
     
  2. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    А в чем, собственно, проблема? Ты не знаешь, как аяксу ответ отдать, или что?
    Серверу плевать, кто его спрашивает. Он так же отдает ответ. Тебе надо просто его обработать. Отдавай в виде JSON, тогда любую структуру данных без проблем упакуешь-распакуешь.
     
  3. smartCreate

    smartCreate Новичок

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4
    Именно так..., не знаю, если не сложно, подскажи пожалуйста, некогда раньше не сталкивался(
     
  4. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Для сервера запрос от аякса - это такой же запрос от браузера. Он его просто обрабатывает. И просто отдает в ответ. То есть у тебя в аякс приходит тот текст, что ты выплюнешь с сервера. Если это HTML, то там HTML. Но так не советую делать. Тебе лучше отдавать JSON с ошибкой, описанием и тд, а там уже доставать это значение на стороне JS и на страницу втыкать.
     
  5. smartCreate

    smartCreate Новичок

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4
    Извини за туговатость, но у меня с синтаксисом еще плоховато из-а недостатка опыта, не мог бы помочь мне разобраться?

    Из того что ты сказал, я переделал скрипт на сервере вот таким образом:
    PHP:
    1. function add_feeds() {
    2.         $config['upload_path'] = './library/img/news/';
    3.         $config['allowed_types'] = 'gif|jpg|png|jpeg';
    4.         $config['max_size']    = '500';
    5.         $config['max_width']  = '1024';
    6.         $config['max_height']  = '768';
    7.         $config['encrypt_name']    = TRUE;
    8.         $config['remove_spaces'] = TRUE;
    9.         $this->load->library('upload', $config);
    10.    
    11.         if ( ! $this->upload->do_upload()) exit (json_encode($error = array('error' => $this->upload->display_errors())));{
    12.             $this->load->view('pages/feeds/index', $error);
    13.         }else{
    14.             $image_data = $this->upload->data();
    15.            
    16.             $feeds['title']  = $_POST['title'];
    17.             $feeds['txt'] = $_POST['txt'];
    18.             $feeds['key_n'] = $_POST['key_n'];
    19.             $feeds['img'] = $image_data['file_name'];
    20.            
    21.             echo json_encode($feeds);
    22.             $this->main_model->new_feeds($feeds);
    23.         }
    24.        
    25.     }
    Не уверен что сделал правильно..., но в любом случаи не совсем понимаю как обработать результат в аяксе, опять же с синтаксисом разобраться не могу(
     
  6. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Тогда я тебе помочь не смогу. Синтаксис растолковывать, увы, у меня особо времени нет. Но могу дать совет - прежде чем вслепую сразу воротить что-то сложное, найди инфу по этому поводу, и собери что-нибудь простенькое, чтобы понимание пришло.

    Ну там..аяксовый скриптик, который раз в секунду обновляет циферку на экране. Пойми как это работает, и поймешь, как тебе сделать что-то сложное.
     
  7. smartCreate

    smartCreate Новичок

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4

    Все не на столько плохо, я понимаю как работает аякс. До меня не как не дойдет, как условие правильно написать на сервере и как принять результат в error моего аякса, я просто банально с этим некогда не работал, даже не знаю как так вышло, но вышло. Я не прошу делать за меня или учить меня синтаксису, я просто не где не могу найти нормальную информацию, по моей проблеме. Если ты понимаешь что нужно, но нет времени объяснить или показать, скинь пожалуйста хоть материал какой-то - был бы невероятно благодарен
     
  8. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Вот и поработайте, на примере чего-то элементарного. Чтобы было не только теоретическое понимание, но и понимание механики процесса.
    Попробуйте один из примеров, лучше первый, с таймером. Он крайне наглядный. И сразу поймете, что вам делать дальше.
     
  9. marsik

    marsik Активный пользователь

    С нами с:
    30 дек 2008
    Сообщения:
    246
    Симпатии:
    17
    наверное как-то так:
    Код (Javascript):
    1. error: function() {
    2. $("#result").text('некая ошибка'); //показываем ошибку на странице, например в <p id="result"></p>
    3. }
     
  10. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Нет. Ни то ни то. error - это если произошла реальная ошибка. Ошибка же автора приходит с кодом 200, это вполне корректный ответ сервера. Это не ошибка выполнения или запроса, это просто серверу не нравится контент, который ему передали. Результат этого запроса будет передан в success.
     
  11. marsik

    marsik Активный пользователь

    С нами с:
    30 дек 2008
    Сообщения:
    246
    Симпатии:
    17
    Ну он же получает данные в data, туда и передавать данные, типа
    Код (Javascript):
    1. if(data.myerror) $("#result").text(data.myerror);
     
  12. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Вы предлагаете ему делать это в обработчике error:function(), это неправильно и не будет работать. Код обработки должен быть в success:function(data);
     
  13. marsik

    marsik Активный пользователь

    С нами с:
    30 дек 2008
    Сообщения:
    246
    Симпатии:
    17
    Код обработки не обязательно должен быть в success:function(data) - То что ТС хочет сделать посредством php (существуют ограничения на расширение файла, вес, размер), можно проверить на js до отправки запроса через ajax
     
    Fell-x27 нравится это.
  14. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Безусловно. И можно и нужно. Больше предварительной валидации на клиенте - меньше холостых запросов к серверу.

    Но он хочет именно так. У него уже есть инфраструктура для этого, просто хочет синхрон на асинхрон поменять. Знаний JS нет. Есть знание жиквери-копипасты, но условное. Потом подрастет в плане навыков, перепишет по-правильному.
     
  15. smartCreate

    smartCreate Новичок

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4
    Спасибо за столь активное внимание к моей теме) Дело на самом деле не в бездумном копипасте кодов джейквери. Просто есть такая штука как опыт, его мне вчера и не хватило, сегодня пол дня посидел и разобрался, вдруг кому нужно будет вот что вышло:
    PHP:
    1. // Условие в обработчике на сервере
    2. if ( ! $this->upload->do_upload()){
    3.         echo json_encode($error = array('error' => $this->upload->display_errors()));
    4. }else{
    5.         $image_data = $this->upload->data();
    6.         $feeds['title']  = $_POST['title'];
    7.         $feeds['txt'] = $_POST['txt'];
    8.         $feeds['key_n'] = $_POST['key_n'];
    9.         $feeds['img'] = $image_data['file_name'];
    10.  
    11.         $this->main_model->new_feeds($feeds);
    12.         echo json_encode($feeds);
    13. }
    Код (Javascript):
    1. // Обработка полученного $error на клиенте
    2. success: function(data) {
    3.         if(data.error) {
    4.                alert(data.error);
    5.         }else{
    6.                alert('ВСЕ ОК');
    7.         }
    8.  });
    А проверяю я коректность отправляемого файла не на клиенте, не потому что делать нечего или не знаю как это сделать, а просто так уж вышло что в начале своего "пути" связался с фреймворком Codignaiter, а у этого засранца свои методы обработки и загрузки файлов, приходиться к ним приспосабливаться.

    Всем спасибо, тема закрыта ))
     
    Fell-x27 нравится это.
  16. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    А никто не говорит, что не надо ничего проверять на сервере. Надо, еще как. Обязательно надо. Мало ли кто и что будет нам пытаться загрузить, не используя браузер. Заливание шелла под видом картиночки - это ж классика.

    НО...при этом никто не мешает первичную проверку проводить на клиенте. Это благо для всех.
    1) Клиент сразу узнаёт, что что-то не так. Ему не надо ждать, пока файл загрузится и прожуется сервером. Жители отдаленных регионов и севера скажут огромное спасибо.
    2) Серверу не надо впустую грузить файлы и проверять их. Да, все равно могут валидацию отключить на клиенте и сунуть всякое, но...это один из тысячи. И тут серверная проверка отработает как надо. А остальные 999 из тысячи некорректных запросов и вовсе не дойдут до сервера. Пусть он лучше тратит свои ресурсы на полезную нагрузку.
     
  17. smartCreate

    smartCreate Новичок

    С нами с:
    4 ноя 2016
    Сообщения:
    122
    Симпатии:
    4
    Спасибо конечно) я это обязательно учту, хотя я это все и раньше знал/понимал, но повторение -мать учение, по этому спасибо что не поленился написать это разъяснение. Вопрос просто изначально не в целесообразности валидации на сервере был, а в том как ошибку при этой самой валидации показать клиенту
     
  18. Fell-x27

    Fell-x27 Суперстар
    Команда форума Модератор

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.771
    Адрес:
    :сердА
    Понятное дело, но мы же беседуем. Беседа дошла до проблемы валидации, которой не все уделяют должное внимание. Более того, твоя серверная валидация с аяксом никак не исключает клиентскую поверх. Для пользователя будет выглядеть одинаково, если одинаково обыграешь в коде.