Error function xhr ajaxoptions thrownerror

В этой статье примеры кода, которые я использую, для отправки ajax-запросов к серверу через jQuery от самых простых и коротких до более продвинутых.

В этой статье примеры кода, которые я использую, для отправки ajax-запросов к серверу через jQuery. Их задачи могут быть разными, поэтому под них можно использовать разные функции, которые упрощают написание кода.

Запрос html-данных с помощью функции Load

Это самый простой ajax-запрос через jQuery с получением html-данных и их вставкой в dom-элемент с id=»result» (содержимое элемента заменяется):

$('#result').load('<url-адрес>');

Более продвинутый вариант использования load:

$('#result').load('<url-адрес>', {par1:val1, par2:val2, ...}, function(response, status, xhr) {
  if (status == 'success') {
    alert('Готово');
  } else {
    alert('Ошибка: ' + xhr.status + ' ' + xhr.statusText);
  }
});

В этом примере серверу так же передаются параметры, а после получения ответа проверяется не было ли ошибки (например, ответ от сервера не был получен) и выполнение различных действий.

Ajax-запросы функциями GET и POST

Эти функции осуществляют отправку ajax запроса http-методами get и post. Приведу пару примеров их использования.

$.get(
  '<url-адрес>',          // адрес отправки запроса
  {par1:val1, par2:val2, ...},  // передача с запросом каких-нибудь данных
  function(data) {              
    // какие-то действия с полученными от сервера данными data
  }
);

Передача данных не обязательна, как и выполнение каких-либо действий после получения ответа от сервера, т.е. в этом случае, строчки 3 и 4-6 можно удалить при необходимости и таким образом еще сократить код.

Тип получаемых от сервера данных можно указать, добавив dataType (см.ниже) — по-умолчанию определяется автоматически.

Использование post аналогично, но в следующем примере использую вызов функции после получения ответа от сервера.

$.post(
  '<url-адрес>',
  {par1:val1, par2:val2, ...},
  onSuccess
);

function onSuccess(data) {
  // какие-то действия с полученными от сервера данными data
}

На самом деле, функции get и post являются сокращенными вариантами функции ajax, которую рассмотрю ниже.

Получение json-данных с помощью getJSON

getJSON — укороченный вариант ajax-запроса методом GET и получением данных в виде json. Способ удобен, например, для получения какого-то массива с данными и последующей работы с ним.

$.getJSON('<url-адрес>', {par1:val1, par2:val2, ...}).success(function(data) {
  // что-то делаем с данными, например, обходим их в цикле и выводим:
  for (var i=0; i<data.length; i++) {
    console.log(data[i].text);
  }
}).error(function(xhr, textStatus, errorThrown) {
  alert('Ошибка: ' + textStatus+' '+errorThrown);
});

На стороне сервера программа формирует массив и преобразовывает его в json-строку, например, так:

$arr = array();
$arr[0] = array('id' => 10, 'text' => 'тестовая строка 1');
$arr[1] = array('id' => 20, 'text' => 'тестовая строка 2');
$arr[2] = array('id' => 30, 'text' => 'тестовая строка 3');
echo json_encode($arr);

Точно так же можно передать с сервера и объекты stdClass, преобразовав их в json-строку.

Простой ajax-запрос через jQuery с помощью функции AJAX

Теперь приведу пример простого get запроса функцией ajax и получением html-данных.

$.ajax({
  url: '<url-адрес>',
  dataType: 'html',
  success: function(data) {
    // какие-то действия с полученными данными data
  }
});

Запрос к серверу происходит get-методом, т.к. параметр, отвечающий за тип запроса, type по-умолчанию равен GET.

Более сложный пример ajax-запроса через jQuery

Пример выполнения запроса функцией ajax с передачей данных post методом и обработкой событий. Ниже опишу дополнительные параметры, которые чаще всего применяются.

$.ajax({
  url: '<url-адрес>',
  type: 'post',
  data: '<отправляемые_данные>', // можно строкой, а можно, например, так: $('input[type="text"], input[type="radio"]:checked, input[type="checkbox"]:checked, select, textarea')
  dataType: 'json',
  beforeSend: function() {
    $('#sendajax').button('loading');
  },
  complete: function() {
    $('#sendajax').button('reset');
  },
  success: function(json) {
    // какие-то действия с полученными данными
  },
  error: function(xhr, ajaxOptions, thrownError) {
    alert(thrownError + "rn" + xhr.statusText + "rn" + xhr.responseText);
  }
});

Кнопка отправки данных:

<button class="btn btn-primary" data-loading-text="Отправка..." id="sendajax" type="button">Отправить</button>

В приведенном примере при нажатии на кнопку button, сначала меняется состояние кнопки (текст на ней меняется на «Отправка…» и она становится не активной), что делается при помощи параметра beforeSend. Затем происходит отправка запроса с передачей нужных данных. После того, как получен ответ от сервера состояние кнопки возвращается в прежнее (текст меняется на «Отправить», становится активной). Ответ получается в виде json-данных.

Коротко опишу параметры отправки ajax-запроса, которые чаще всего могут пригодиться:

url Адрес отправки ajax-запроса
type Способ отправки запроса GET или POST
data Отправляемые серверу данные. Может быть строка с параметрами и их значениями в формате par1=val1&par2=val2&…, объект jQuery, например, $(‘input[type=»text»]’) или другие данные.
dataType Тип получаемых от сервера данных. Может быть html, json, text, script и xml.
cache Кэширование браузером запроса (false — не кэшировать).
async Асинхронное выполнение запроса, т.е. программа продолжает выполняться не дожидаясь ответа сервера. Если указать false, то запрос будет выполнен синхронно, при этом страница не будет ни на что реагировать, пока не будет получен ответ от сервера.
processData Преобразование отправляемых данных в url-формат. Если нужно чтобы данные не преобразовывались, установить в false. Например, при отправке изображения на сервер или xml-данных.
contentType Тип передаваемых данных, по умолчанию «application/x-www-form-urlencoded; charset=UTF-8». Если указать false, то в заголовке не будет передаваться тип, что может быть необходимо, например, при отправке изображения на сервер.
beforeSend Функция, выполняемая перед отправкой ajax-запроса.
complete Функция, выполняемая после получения ответа от сервера (любого, успешного или нет).
success Функция, выполняемая при удачном выполнении запроса.
error Функция, выполняемая в случае ошибки.

Ниже приведу еще несколько примеров использования ajax-запросов.

Отправка формы со всеми данными ajax-запросом через jQuery

Примерный код html-формы:

<form id="myform" action="" method="POST">
  <label for="user_name">Ваше имя:</label>
  <input name="user_name" value="" type="text" />
  <input type="submit" value="Отправить">
</form>

JavaScript код:

$('#myform').submit(function(e) {
  e.preventDefault();
  $.ajax({
    type: $(this).attr('method'),
    url: '<url-адрес>',
    data: $(this).serialize(),
    async: false,
    dataType: "html",
    success: function(result){
      alert('Форма отправлена');
    }
  });
});

Для того чтобы страница не перезагружалась при нажатии на кнопку «submit», сначала отменяем стандартые действия браузера использовав e.preventDefaults().

В параметре data мы передаем все поля формы использовав $(this).serialize() — эта функция преобразует все input-ы и select-ы в строку, пригодную для отправки на сервер.

Так же, здесь использован параметр async: false, чтобы пока форма не отправится на сервер больше ничего нельзя было нажать или сделать.

Отправка изображения или файла ajax-запросом через jQuery

Задача отправки файла или изображения на сервер без перезагрузки страницы довольно часто возникает. В этом примере разберу сразу 2 фишки: выбор файла по нажатию на кнопку, которая может быть оформлена как угодно, и отображение прогресса при передаче файла на сервер ajax-запросом.

html-код будет такой:

<button id="addfile"><span>Загрузить изображение</span><input type="file" id="load_file" value=""></button>

css код:

#addfile {
  position: relative;
  overflow: hidden;
  width: 180px;
  height: 34px;
}
#load_file {
  position: absolute;
  top: 0;
  left: 0;
  width: 180px;
  height: 34px;
  font-size: 0px;
  opacity: 0;
  filter: alpha(opacity:0);
}
#load_file:hover {
  cursor: pointer;
}

Суть идеи в том, что поверх кнопки выводится стандартный input для выбора файла, но он полностью прозрачен и имеет такие же размеры как кнопка. Таким образом, пользователь видит кнопку button, но когда наводит на нее курсор, фактически наводит на input. Соответственно, когда он нажимает на кнопку, на самом деле нажимается input выбора файла. Для того, чтобы не мигал курсор после выбора файла, размер шрифта задан 0px.

Теперь javascript код отправки файла на сервер с отображением прогресса:

$(function() {
  $('#load_file').on('change', loadfile);
});

function loadfile() {
  $('#addfile span').html('Загружено 0 %');
  files = $('#load_file')[0].files;
  var form = new FormData();
  form.append('upload', files[0]);
  $.ajax({
    url: '<url-адрес>',
    type: 'POST',
    data: form,
    cache: false,
    processData: false,
    contentType: false,
    xhr: function() {
      var myXhr = $.ajaxSettings.xhr();
      if (myXhr.upload) {
        myXhr.upload.addEventListener('progress',ShowProgress, false);
      }
      return myXhr;
    },
    complete: function(data){
      $('#addfile span').html('Загрузить изображение');
      $('#load_file').val('');
    },
    success: function(message){
      alert(message);
    },
    error: function(jqXHR, textStatus, errorThrown) {
      alert(textStatus+' '+errorThrown);
    }
  });
}

function ShowProgress(e) {
  if(e.lengthComputable){
    $('#addfile span').html('Загружено '+Math.round(100*e.loaded/e.total)+' %');
  }
}

При загрузке файла на сервер в кнопке будет показываться сколько % уже передано на сервер. После завершения загрузки название кнопки возвращается как было, а значение input-а с файлом устанавливается пустым, чтобы можно было снова выбирать новый файл.

Пример серверной части на php (по просьбе Евгения):

  $message = '';
  if (empty($_FILES['upload']['name']) || $_FILES['upload'] == "none") {
    $message = 'Вы не выбрали файл';
  } else if ($_FILES['upload']['size'] == 0 || $_FILES['upload']['size'] > 9437184) {
    $message = 'Размер файла не соответствует нормам (максимум 9 Мб)';
  } else if (($_FILES['upload']['type'] != 'image/jpeg') && ($_FILES['upload']['type'] != 'image/pjpeg') &&
             ($_FILES['upload']['type'] != 'image/gif') && ($_FILES['upload']['type'] != 'image/png')) {
    $message = 'Допускается загрузка только картинок JPG, GIF и PNG.';
  } else if (!is_uploaded_file($_FILES['upload']['tmp_name'])) {
    $message = 'Что-то пошло не так. Попытайтесь загрузить файл ещё раз.';
  } else {
    $ftype = $_FILES['upload']['type'];
    $fname = 'newname_image.'.($ftype == 'image/gif' ? 'gif' : ($ftype == 'image/png' ? 'png' : 'jpg'));
    if (move_uploaded_file($_FILES['upload']['tmp_name'], $_SERVER['DOCUMENT_ROOT'].'/files/'.$fname)) {
      $message = 'Изображение успешно загружено.';
    } else {
      $message = 'Что-то пошло не так. Попытайтесь загрузить файл ещё раз.';
    }
  }
  exit($message);

Информация о загруженном изображении будет содержаться в $_FILES[‘upload’], т.к. скриптом файл добавлялся так: form.append(‘upload’, files[0]); Соответственно, всё что требуется от php-программы — это проверить что файл соответствует ожидаемым параметрам, перенести файл в нужную папку (в примере в папку files) под нужным именем (в примере newname_image) и вернуть в браузер ответ, который в моем примере просто выводится пользователю командой alert(message);

Ситуаций, в которых можно и даже нужно использовать ajax-запросы, очень много и все их здесь не разобрать. Тем не менее, если есть предложения, какие еще примеры имеет смысл сюда добавить, пишите в комментариях.

Эта функция в основном генерирует уникальный случайный ключ API, и в случае, если это не так, появляется всплывающее диалоговое окно с сообщением об ошибке.

На странице просмотра:

<div class="form-group required">
    <label class="col-sm-2 control-label" for="input-storename"><?php echo $entry_storename; ?></label>
    <div class="col-sm-6">
        <input type="text" class="apivalue"  id="api_text" readonly name="API" value="<?php echo strtoupper(substr(md5(rand().microtime()), 0, 12)); ?>" class="form-control" />                                                                    
        <button type="button" class="changeKey1" value="Refresh">Re-Generate</button>
    </div>
</div>

<script>
$(document).ready(function(){
    $('.changeKey1').click(function(){
          debugger;
        $.ajax({
                url  :"index.php?route=account/apiaccess/regenerate",
                type :'POST',
                dataType: "json",
                async:false,
                contentType: "application/json; charset=utf-8",
                success: function(data){
                  var result =  data.sync_id.toUpperCase();
                        if(result){
                          $('#api_text').val(result);
                        }
                  debugger;
                  },
                error: function(xhr, ajaxOptions, thrownError) {
                  alert(thrownError + "rn" + xhr.statusText + "rn" + xhr.responseText);
                }

        });
    });
  });
</script>

С контроллера:

public function regenerate(){
    $json = array();
    $api_key = substr(md5(rand(0,100).microtime()), 0, 12);
    $json['sync_id'] = $api_key; 
    $json['message'] = 'Successfully API Generated';
    $this->response->addHeader('Content-Type: application/json');
    $this->response->setOutput(json_encode($json));
}

Необязательный параметр обратного вызова указывает функцию обратного вызова, запускаемую после завершения метода load (). Функция обратного вызова может иметь разные параметры:

Тип: Функция (jqXHR jqXHR, String textStatus, String errorThrown)

Функция, вызываемая в случае сбоя запроса. Функция получает три аргумента: объект jqXHR (в jQuery 1.4.x, XMLHttpRequest), строку, описывающую тип произошедшей ошибки, и необязательный объект исключения, если таковая произошла. Возможные значения для второго аргумента (помимо нуля): «тайм-аут», «ошибка», «прерывание» и «ошибка синтаксического анализа». Когда возникает ошибка HTTP, errorThrown получает текстовую часть статуса HTTP, например «Не найден» или «Внутренняя ошибка сервера». Начиная с jQuery 1.5, параметр ошибки может принимать массив функций. Каждая функция будет вызываться по очереди. Примечание. Этот обработчик не вызывается для междоменных скриптов и междоменных запросов JSONP.

Эта функция в основном генерирует уникальный случайный ключ API, а если нет, то появляется всплывающее диалоговое окно с сообщением об ошибке

На странице просмотра:

<div class="form-group required">
    <label class="col-sm-2 control-label" for="input-storename"><?php echo $entry_storename; ?></label>
    <div class="col-sm-6">
        <input type="text" class="apivalue"  id="api_text" readonly name="API" value="<?php echo strtoupper(substr(md5(rand().microtime()), 0, 12)); ?>" class="form-control" />                                                                    
        <button type="button" class="changeKey1" value="Refresh">Re-Generate</button>
    </div>
</div>

<script>
$(document).ready(function(){
    $('.changeKey1').click(function(){
          debugger;
        $.ajax({
                url  :"index.php?route=account/apiaccess/regenerate",
                type :'POST',
                dataType: "json",
                async:false,
                contentType: "application/json; charset=utf-8",
                success: function(data){
                  var result =  data.sync_id.toUpperCase();
                        if(result){
                          $('#api_text').val(result);
                        }
                  debugger;
                  },
                error: function(xhr, ajaxOptions, thrownError) {
                  alert(thrownError + "rn" + xhr.statusText + "rn" + xhr.responseText);
                }

        });
    });
  });
</script>

От контроллера:

public function regenerate(){
    $json = array();
    $api_key = substr(md5(rand(0,100).microtime()), 0, 12);
    $json['sync_id'] = $api_key; 
    $json['message'] = 'Successfully API Generated';
    $this->response->addHeader('Content-Type: application/json');
    $this->response->setOutput(json_encode($json));
}

Опциональный параметр обратного вызова указывает функцию обратного вызова, которая должна выполняться при завершении метода load(). Функция обратного вызова может иметь разные параметры:

Тип: Функция (jqXHR jqXHR, String textStatus, String errorThrown)

Функция, вызываемая, если запрос терпит неудачу. Функция получает три аргумента: объект jqXHR (в jQuery 1.4.x, XMLHttpRequest), строка, описывающая тип возникшей ошибки и необязательный объект исключения, если это произошло. Возможные значения для второго аргумента (кроме нуля) — это «тайм-аут», «ошибка», «прервать» и «parsererror». При возникновении ошибки HTTP errorThrown получает текстовую часть статуса HTTP, например «Not Found» или «Internal Server Error». Начиная с jQuery 1.5, параметр ошибки может принимать массив функций. Каждая функция будет вызываться по очереди. Примечание. Этот обработчик не вызывается для междоменного скрипта и междоменных запросов JSONP.

In this tutorial, we will show you how to send an Ajax request after the web page has loaded.

In this guide, we will be using the jQuery library to send a simple Ajax request after the document has finished loading.

Let’s take a look at a basic example.

<html>
    <head>
        <meta charset="UTF-8">
        <title>Ajax Call After Page Load</title>
    </head>
    <body>
        
        <!-- Content is blank by default -->
        <div id="content"></div>
        
        <!-- Include the JQuery library -->
        <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
        <script>
        //When the page has loaded.
        $( document ).ready(function(){
            //Perform Ajax request.
            $.ajax({
                url: 'test.html',
                type: 'get',
                success: function(data){
                    //If the success function is executed,
                    //then the Ajax request was successful.
                    //Add the data we received in our Ajax
                    //request to the "content" div.
                    $('#content').html(data);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    var errorMsg = 'Ajax request failed: ' + xhr.responseText;
                    $('#content').html(errorMsg);
                  }
            });
        });
        </script>
    </body>
</html>

An explanation of the code above.

  1. We create an empty DIV element. We give this element the ID “content” so that we can easily reference it and manipulate it with JavaScript.
  2. After that, we include the jQuery library. jQuery is useful as it eliminates a lot of the tedious work that regular vanilla JavaScript Ajax request often require.
  3. We use the JQuery ready function. This function is important as it prevents our JavaScript code from executing until the page has loaded.
  4. Inside the ready function, we perform a simple GET Ajax request to a file called “test.html”. If you are testing the script above, simply create a “test.html” file and then add it to the same folder that your web page is currently situated in. Make sure that you add some text to the file. For example, I added “Hello World!” to mine.
  5. If the Ajax request is successful (if a 200 OK HTTP response code is returned), then the success function is executed. Inside this success function, we simply add the data that is returned from our request to the “content” div by using the html function. The html function will replace whatever is inside the “content” div.
  6. We also setup an error function. This error function will display an error message in the “content” div if the request fails. For example, if the Ajax request encounters a 404 Not Found or 500 internal Error.

Hopefully, you found this tutorial useful!

jQuery AJAX

Определение и применение

jQuery метод .ajaxError() позволяет задать функцию (обработчик события), которая вызывается в том случае, если AJAX запрос завершился ошибкой.


Каждый раз, когда AJAX запрос завершается ошибкой, jQuery инициирует событие ajaxError, при этом все обработчики события, которые были зарегистрированы при помощи метода .ajaxError() будут выполнены в данный момент.

Обращаю Ваше внимание, что этот обработчик не вызывается для кроссдоменных скриптов и кроссдоменных JSONP запросов.


Если методы $.ajax(), или $.ajaxSetup() используются с установленным параметром global со значением false, то обработчик ajaxError не будет вызван. Начиная с версии jQuery 1.9, все обработчики для глобальных AJAX событий, должны быть прикреплены к объекту document следующием образом:

$( document ).ajaxEvent( handler ) // пример добавления обработчика для глобального AJAX события

jQuery синтаксис:

Синтаксис 1.0:
.ajaxError( handler )

handler - Function( Event event, jqXHR jqXHR, PlainObject ajaxOptions, String thrownError )

Добавлен в версии jQuery

1.0

Значения параметров

Параметр Описание
handler Задает функцию, которая будет выполнена в том случае, если AJAX запрос завершился ошибкой. Является обязательным параметром метода. Функция принимает следующие параметры:

  • event — содержит объект события Event.
  • jqXHR — содержит объект XMLHTTPRequest
  • ajaxOptions — содержит параметры, используемые в AJAX запросе.
  • thrownError — в случае возникновения HTTP ошибки содержит её текстовой статус в виде строки (например, «Not Found», или «Internal Server Error»)

Пример использования

<!DOCTYPE html>
<html>
	<head>
		<title>Использование метода .ajaxError()</title>
		<script src = "https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
		<script>
	$( document ).ready(function(){
	  $( "button" ).click(function(){ // задаем функцию при нажатиии на элемент <button>
	    $( "div" ).load( "missed.php" ); // с использованием AJAX запроса пытаемся загрузить данные с сервера и разместить возвращенный HTML код внутри элемента <div>
	  });
	  $( document ).ajaxError(function( event, xhr, options, thrownError ){ // добавляем обработчик события
	    if ( options.url == "missed.php" ) // если в объекте, содержащим настройки AJAX запроса ключ url содержит значение missed.php
	      $( "span" ).text( "it's ajaxError" ); // то добавить в элемент  <span> текстовое содержимое
	    console.log( thrownError ); // выводим в консоль информацию об ошибке
	  })
	});
		</script>
	</head>
	<body>
		<button>Клик</button><span></span>
		<br><br>
		<div></div>
	</body>
</html>

В этом примере с использованием jQuery метода .load() мы при нажатии на элемент <button> (кнопка) с использованием AJAX запроса пытаемся загрузить данные с сервера и разместить возвращенный HTML код внутри элемента <div>. Загружаемый файл («missed.php«) отсутствует, что приводит к ошибке.

С использованием метода .ajaxError() задаем функцию (обработчик события), которая вызывается каждый раз после того как AJAX запрос завершился ошибкой. Функция производит проверку на наличие в объекте, содержащего настройки AJAX запроса ключа «url», который содержит значение missed.php. Если содержит, то в элемент <span> с использованием метода .text() производит добавление текстового содержимого. Кроме того, мы выводим в консоль информацию об ошибке HTTP (текстовый статус). В нашем случае — «Not Found».

Результат нашего примера:

Пример использования jQuery метода .ajaxError().

Пример использования jQuery метода .ajaxError()
jQuery AJAX

Как использовать Ajax в OpenCart

От автора: благодаря тому, что в ядре OpenCart присутствует библиотека JQuery, работа с Ajax становится крайне простой. На деле же, по всем файлам фреймворка разбросаны небольшие, но значимые вкрапления на JQuery. В этой статье мы создадим веб-страницу и продемонстрируем с ее помощью работу Ajax в OpenCart.

Страница будет иметь простой интерфейс с выпадающим списком товаров и блоком, в котором отображается вся информация по выбранному товару. Изюминка будущего демо заключается в том, что блок с информацией о товаре будет строиться с помощью Ajax на лету. Сам пример не будет каким-то сверх сложным, однако, как я думаю, он послужит своей главной цели и покажет базовое взаимодействие Ajax и OpenCart.

Предполагается, что вы работаете из-под последней версии OpenCart 2.1.x.x! Так как основная тема статьи это взаимодействие Ajax и OpenCart, я быстро расскажу про разработку собственных модулей в OpenCart. И даже если вы совсем не понимаете, о чем идет речь, вам на помощь придут небольшие объяснения кода в комментариях, чтобы вы смогли дойти с нами до конца статьи!

Быстрый взгляд на организацию файлов

По-быстрому рассмотрим необходимые файлы нашей страницы.

catalog/controller/ajax/index.php: Файл контроллера, в котором прописана логика стандартного контроллера в OpenCart.

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC

В курсе 39 уроков | 15 часов видео | исходники для каждого урока

Получить курс сейчас!

catalog/language/english/ajax/index.php: файл языка.

catalog/view/theme/default/template/ajax/index.tpl: Файл шаблона представления, в котором хранится XHTML нашей страницы.

catalog/view/theme/default/template/ajax/product.tpl: Файл шаблона представления, в котором хранится XHTML код AJAX ответа.

Краткий список файлов, с которыми мы будем работать.

Создаем файлы модуля

Давайте продолжим и создадим файл catalog/controller/ajax/index.php и скопируем в него следующий код.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

<?php

// catalog/controller/ajax/index.php

class ControllerAjaxIndex extends Controller {

  public function index() {

    $this>load>language(‘ajax/index’);

    $this>load>model(‘catalog/product’);

    $this>document>setTitle($this>language>get(‘heading_title’));

    // загружаем все товары

    $products = $this>model_catalog_product>getProducts();

    $data[‘products’] = $products;

    $data[‘breadcrumbs’] = array();

    $data[‘breadcrumbs’][] = array(

      ‘href’ => $this>url>link(‘common/home’),

      ‘text’ => $this>language>get(‘text_home’)

    );

    $data[‘breadcrumbs’][] = array(

      ‘href’ => $this>url>link(‘ajax/index’),

      ‘text’ => $this>language>get(‘heading_title’)

    );

    $data[‘heading_title’] = $this>language>get(‘heading_title’);

    $data[‘text_product_dropdown_label’] = $this>language>get(‘text_product_dropdown_label’);

    $data[‘column_left’] = $this>load>controller(‘common/column_left’);

    $data[‘column_right’] = $this>load>controller(‘common/column_right’);

    $data[‘content_top’] = $this>load>controller(‘common/content_top’);

    $data[‘content_bottom’] = $this>load>controller(‘common/content_bottom’);

    $data[‘footer’] = $this>load>controller(‘common/footer’);

    $data[‘header’] = $this>load>controller(‘common/header’);

    if (file_exists(DIR_TEMPLATE . $this>config>get(‘config_template’) . ‘/template/ajax/index.tpl’)) {

      $this>response>setOutput($this>load>view($this>config>get(‘config_template’) . ‘/template/ajax/index.tpl’, $data));

    } else {

      $this>response>setOutput($this>load>view(‘default/template/ajax/index.tpl’, $data));

    }

  }

  // метод вызова ajax

  public function ajaxGetProduct() {

    if (isset($this>request>get[‘product_id’])) {

      $product_id = (int) $this>request>get[‘product_id’];

      if ($product_id > 0) {

        // загружаем определенный товар, запрошенный в ajax

        $this>load>model(‘catalog/product’);

        $product = $this>model_catalog_product>getProduct($product_id);

        $data[‘product’] = $product;

        // подготавливаем превью изображения

        $this>load>model(‘tool/image’);

        if ($product[‘image’]) {

          $data[‘thumb’] = $this>model_tool_image>resize($product[‘image’], $this>config>get(‘config_image_thumb_width’), $this>config>get(‘config_image_thumb_height’));

        }

        // форматируем цену

        $data[‘price’] = $this>currency>format($this>tax>calculate($product[‘price’], $product[‘tax_class_id’], $this>config>get(‘config_tax’)));

        $this>load>language(‘product/product’);

        $data[‘text_manufacturer’] = $this>language>get(‘text_manufacturer’);

        $data[‘text_model’] = $this>language>get(‘text_model’);

        $data[‘text_note’] = $this>language>get(‘text_note’);

        $data[‘tab_description’] = $this>language>get(‘tab_description’);

        if (file_exists(DIR_TEMPLATE . $this>config>get(‘config_template’) . ‘/template/ajax/product.tpl’)) {

          $this>response>setOutput($this>load>view($this>config>get(‘config_template’) . ‘/template/ajax/product.tpl’, $data));

        } else {

          $this>response>setOutput($this>load>view(‘default/template/ajax/product.tpl’, $data));

        }

      }

    }

  }

}

Метод index данного контроллера используется для загрузки языка и файлов модели, а также с его помощью задаются общие переменные для стандартного шаблона OpenCart. Так как мы будем загружать модель товаров из самого ядра, нам не нужно дублировать код для того, чтобы получить информацию о товарах.

После загрузки модели товаров с помощью метода getProducts мы загружаем все товары. В конце мы подходим к методу index, задав index.tpl, как в нашем файле основного шаблона.

Следом идет крайне важный метод ajaxGetProduct, с помощью которого строится блок с данными о товаре по его идентификатору, передаваемому в Ajax метод (это мы совсем скоро увидим в файле шаблона). Данный метод загружает ту же самую модель, что и метод index, но кроме этого он еще и запускает функцию getProduct, которая вытягивает информацию о товаре по его ID.

В конце в качестве шаблона для данного метода задается шаблон product.tpl. В рамках нашего примера мы используем шаблон для создания ответа из Ajax’а, но вы вполне можете воспользоваться JSON строкой.

Едем дальше, создадим файл языка catalog/language/english/ajax/index.php, в котором будем хранить простые подписи.

<?php

// catalog/language/english/ajax/index.php

// заголовок

$_[‘heading_title’]            = ‘Simple Ajax Example’;

$_[‘text_product_dropdown_label’]   = ‘Select Product’;

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC

В курсе 39 уроков | 15 часов видео | исходники для каждого урока

Получить курс сейчас!

В рамках данного урока файл шаблона представления важнее остальных. Его необходимо создать в директории catalog/view/theme/default/template/ajax/index.tpl и скопировать в него код ниже.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

<! catalog/view/theme/default/template/ajax/index.tpl >

<?php echo $header; ?>

<div class=«container»>

  <ul class=«breadcrumb»>

    <?php foreach ($breadcrumbs as $breadcrumb) { ?>

    <li><a href=«<?php echo $breadcrumb[‘href’]; ?>«><?php echo $breadcrumb[‘text’]; ?></a></li>

    <?php } ?>

  </ul>

  <div class=«row»><?php echo $column_left; ?>

    <?php if ($column_left && $column_right) { ?>

    <?php $class = ‘col-sm-6’; ?>

    <?php } elseif ($column_left || $column_right) { ?>

    <?php $class = ‘col-sm-9’; ?>

    <?php } else { ?>

    <?php $class = ‘col-sm-12’; ?>

    <?php } ?>

    <div id=«content» class=«<?php echo $class; ?>«><?php echo $content_top; ?>

      <h2><?php echo $heading_title; ?></h2>

      <fieldset id=«account»>

      <div>

        <label class=«col-sm-2 control-label» for=«product»><?php echo $text_product_dropdown_label; ?></label>

        <div class=«col-sm-10»>

          <select name=«product» class=«form-control» id=«product»>

            <option> <?php echo $text_product_dropdown_label; ?> </option>

            <?php foreach ($products as $product) { ?>

              <option value=«<?php echo $product[‘product_id’]; ?>«><?php echo $product[‘name’]; ?></option>

            <?php } ?>

          </select>

        </div>

      </div>

      </fieldset>

      <div id=«product_summary»></div>

      <?php echo $content_bottom; ?></div>

    <?php echo $column_right; ?></div>

</div>

<?php echo $footer; ?>

<script type=«text/javascript»>

  $(‘#product’).on(‘change’, function() {

    $.ajax({

      url: ‘index.php?route=ajax/index/ajaxGetProduct&product_id=’ + this.value,

      dataType: ‘html’,

      success: function(htmlText) {

        $(‘#product_summary’).html(htmlText);

      },

      error: function(xhr, ajaxOptions, thrownError) {

        alert(thrownError + «rn» + xhr.statusText + «rn» + xhr.responseText);

      }

    });

  });

</script>

Нас интересует нижняя часть файла index.tpl, а именно JS код, в котором используются методы JQuery для прикрепления события change и Ajax. После выбора пользователем товара из выпадающего списка запускается событие change, которое сразу же запускает Ajax. В методе ajax к строке запроса GET мы прикрепляем переменную product_id.

Однако как мы уже упоминали выше в настройках контроллера, метод ajaxGetProduct посылает XHTML код блока с дополнительными данными о товаре на основе его product_id. В методе success мы прикрепляем XHTML ответ к тегу DIV с идентификатором product_summary.

И осталось создать последний файл catalog/view/theme/default/template/ajax/product.tpl со следующим кодом для вызова Ajax.

<! catalog/view/theme/default/template/ajax/product.tpl >

<div style=«border: 1px solid #CCC;padding:10px;margin:10px;»>

  <h3><?php echo $product[‘name’]; ?> <?php echo $price; ?></h3>

  <p><img src=«<?php echo $thumb; ?>«/></p>

  <p><b><?php echo $text_manufacturer; ?></b>&nbsp;<?php echo $product[‘manufacturer’]; ?></p>

  <p><b><?php echo $text_model; ?></b>&nbsp;<?php echo $product[‘model’]; ?></p>

</div>

Ничего особенного – самый обычный блок с дополнительной информацией о товаре на XHTML. Итак, копаться в файлах мы закончили. В следующей части мы перейдем к front-end тестам, созданной нами страницы.

Front-end тестирование

С самой сложной частью мы справились, теперь нужно протестировать, что у нас получилось! Перейдите в раздел front-ennd в //www.yourstore.com/index.php?route=ajax/index. Перед вами должен появиться красивый интерфейс, как на скриншоте.

Это наша страница, на которой отображается выпадающий список со всеми товарами. Давайте выберем товар из списка, что должно вызвать Ajax запрос. Прямо под списком появляется довольно красивый блок с общей информацией о товаре.

Если вы делали все точно, как я сказал, то у вас не должно возникнуть проблем. Данный пример довольно простой и показывает лишь базовое взаимодействие Ajax и OpenCart, но вы всегда можете его расширить под свои требования.
Попробуйте поиграться с кодом, создайте что-то интерактивное с помощью Ajax. Это лучший способ понять технологию. На сегодня все, немного позже я расскажу про более увлекательные технологии.

Заключение

В данной статье основное внимание было уделено взаимодействию Ajax и OpenCart. Как и всегда, мы воспользовались методом создания пользовательского модуля для демонстрации технологии.

И как всегда, если вы ищите дополнительные инструменты, утилиты, разрешения и т.д. для работы с OpenCart и хотите интегрировать их в свои проекты или просто поупражняться, не забывайте, что у нас есть свой сайт со всем, что вам нужно.

Надеюсь, статья была для вас информативной и полезной. Не стесняйтесь задавать вопросы и оставлять комментарии!

Автор: Sajal Soni

Источник: //code.tutsplus.com/

Редакция: Команда webformyself.

Бесплатный курс по PHP программированию

Освойте курс и узнайте, как создать динамичный сайт на PHP и MySQL с полного нуля, используя модель MVC

В курсе 39 уроков | 15 часов видео | исходники для каждого урока

Получить курс сейчас!

Разработка веб-приложения на PHP

Скачайте видеокурс и узнайте, как создать веб-приложение на PHP

Скачать

Убедитесь, что вы устанавливаете Response.StatusCode на значение, отличное от 200. Напишите сообщение об исключении, используя Response.Write , затем используйте …

xhr.responseText

..в вашем javascript.

Контроллер:

public class ClientErrorHandler : FilterAttribute, IExceptionFilter
{
    public void OnException(ExceptionContext filterContext)
    {
        var response = filterContext.RequestContext.HttpContext.Response;
        response.Write(filterContext.Exception.Message);
        response.ContentType = MediaTypeNames.Text.Plain;
        filterContext.ExceptionHandled = true;
    }
}

[ClientErrorHandler]
public class SomeController : Controller
{
    [HttpPost]
    public ActionResult SomeAction()
    {
        throw new Exception("Error message");
    }
}

Просмотр скрипта:

$.ajax({
    type: "post", url: "/SomeController/SomeAction",
    success: function (data, text) {
        //...
    },
    error: function (request, status, error) {
        alert(request.responseText);
    }
});

Серверная сторона:

     doPost(HttpServletRequest request, HttpServletResponse response){ 
            try{ //logic
            }catch(ApplicationException exception){ 
               response.setStatus(400);
               response.getWriter().write(exception.getMessage());
               //just added semicolon to end of line

           }
 }

Сторона клиента:

 jQuery.ajax({// just showing error property
           error: function(jqXHR,error, errorThrown) {  
               if(jqXHR.status&&jqXHR.status==400){
                    alert(jqXHR.responseText); 
               }else{
                   alert("Something went wrong");
               }
          }
    }); 

Общая обработка ошибок Ajax

Если мне нужно выполнить общую обработку ошибок для всех запросов ajax. Я установлю обработчик ajaxError и покажу ошибку в div с именем errorcontainer в верхней части содержимого html.

$("div#errorcontainer")
    .ajaxError(
        function(e, x, settings, exception) {
            var message;
            var statusErrorMap = {
                '400' : "Server understood the request, but request content was invalid.",
                '401' : "Unauthorized access.",
                '403' : "Forbidden resource can't be accessed.",
                '500' : "Internal server error.",
                '503' : "Service unavailable."
            };
            if (x.status) {
                message =statusErrorMap[x.status];
                                if(!message){
                                      message="Unknown Error n.";
                                  }
            }else if(exception=='parsererror'){
                message="Error.nParsing JSON Request failed.";
            }else if(exception=='timeout'){
                message="Request Time out.";
            }else if(exception=='abort'){
                message="Request was aborted by the server";
            }else {
                message="Unknown Error n.";
            }
            $(this).css("display","inline");
            $(this).html(message);
                 });

Вам нужно преобразовать responseText в JSON. Используя JQuery:

jsonValue = jQuery.parseJSON( jqXHR.responseText );
console.log(jsonValue.Message);

При вызове asp.net будет возвращен заголовок сообщения об ошибке:

Я сам не писал полностью formatErrorMessage, но считаю его очень полезным.

function formatErrorMessage(jqXHR, exception) {

    if (jqXHR.status === 0) {
        return ('Not connected.nPlease verify your network connection.');
    } else if (jqXHR.status == 404) {
        return ('The requested page not found. [404]');
    } else if (jqXHR.status == 500) {
        return ('Internal Server Error [500].');
    } else if (exception === 'parsererror') {
        return ('Requested JSON parse failed.');
    } else if (exception === 'timeout') {
        return ('Time out error.');
    } else if (exception === 'abort') {
        return ('Ajax request aborted.');
    } else {
        return ('Uncaught Error.n' + jqXHR.responseText);
    }
}


var jqxhr = $.post(addresshere, function() {
  alert("success");
})
.done(function() { alert("second success"); })
.fail(function(xhr, err) { 

    var responseTitle= $(xhr.responseText).filter('title').get(0);
    alert($(responseTitle).text() + "n" + formatErrorMessage(xhr, err) ); 
})

Это то, что я сделал, и до сих пор это работает в приложении MVC 5.

Тип возврата контроллера — ContentResult.

public ContentResult DoSomething()
{
    if(somethingIsTrue)
    {
        Response.StatusCode = 500 //Anything other than 2XX HTTP status codes should work
        Response.Write("My Message");
        return new ContentResult();
    }

    //Do something in here//
    string json = "whatever json goes here";

    return new ContentResult{Content = json, ContentType = "application/json"};
}

А на стороне клиента так выглядит функция ajax

$.ajax({
    type: "POST",
    url: URL,
    data: DATA,
    dataType: "json",
    success: function (json) {
        //Do something with the returned json object.
    },
    error: function (xhr, status, errorThrown) {
        //Here the status code can be retrieved like;
        xhr.status;

        //The message added to Response object in Controller can be retrieved as following.
        xhr.responseText;
    }
});

Если кто-то находится здесь, как в 2016 году, чтобы получить ответ, используйте .fail() для обработки ошибок, поскольку .error() устарело с jQuery 3.0.

$.ajax( "example.php" )
  .done(function() {
    alert( "success" );
  })
  .fail(function(jqXHR, textStatus, errorThrown) {
    //handle error here
  })

Я надеюсь, что это помогает

Общее / многоразовое решение

Этот ответ предназначен для использования в будущем для всех, кто столкнется с этой проблемой. Решение состоит из двух вещей:

  1. Пользовательское исключение ModelStateException которое возникает при сбое проверки на сервере (состояние модели сообщает об ошибках проверки, когда мы используем аннотации данных и параметры действий контроллера со строгой типизацией)
  2. Пользовательский фильтр ошибок действия контроллера HandleModelStateExceptionAttribute который перехватывает настраиваемое исключение и возвращает статус ошибки HTTP с ошибкой состояния модели в теле

Это обеспечивает оптимальную инфраструктуру для вызовов jQuery Ajax, чтобы полностью использовать их потенциал с обработчиками success и error .

Код на стороне клиента

$.ajax({
    type: "POST",
    url: "some/url",
    success: function(data, status, xhr) {
        // handle success
    },
    error: function(xhr, status, error) {
        // handle error
    }
});

Код на стороне сервера

[HandleModelStateException]
public ActionResult Create(User user)
{
    if (!this.ModelState.IsValid)
    {
        throw new ModelStateException(this.ModelState);
    }

    // create new user because validation was successful
}

Вся проблема подробно описана в этом сообщении блога, где вы можете найти весь код для запуска этого в вашем приложении.

Мне это показалось приятным, потому что я мог разбирать сообщение, которое я отправлял с сервера, и отображать дружественное сообщение пользователю без трассировки стека …

error: function (response) {
      var r = jQuery.parseJSON(response.responseText);
      alert("Message: " + r.Message);
      alert("StackTrace: " + r.StackTrace);
      alert("ExceptionType: " + r.ExceptionType);
}

 error:function (xhr, ajaxOptions, thrownError) {
        alert(xhr.status);
        alert(thrownError);
      }

в коде ошибка ajax-запрос для обнаружения ошибки подключения между клиентом и сервером, если вы хотите, чтобы сообщение об ошибке вашего приложения было отправлено в области успеха

такой как

success: function(data){
   //   data is object  send  form server 
   //   property of data 
   //   status  type boolean 
   //   msg     type string
   //   result  type string
  if(data.status){ // true  not error 
         $('#api_text').val(data.result);
  }
  else 
  {
      $('#error_text').val(data.msg);
  }

}

Понравилась статья? Поделить с друзьями:
  • Error function sahara rx data 237 unable to read packet header
  • Error function port connect 100 failed to open com port handle
  • Error function main 320 uploading image using sahara protocol failed
  • Error function main 303 uploading image using sahara protocol failed
  • Error function definitions are not permitted at the prompt or in scripts