Как стать автором
Обновить

Как сократить количество написаного кода при ajax запросах? И ассинхронная отправка файлов

Время на прочтение4 мин
Количество просмотров16K
Итак ajax запросы, всё просто, все привыкли их уже писать, но всё же как можно сократить количество написанного кода.
jquery.async.js

Сразу пример:
<form action="/" jasync>
	<input type="submit" />
</form>
форма отправляется ассинхронно

<input type="file" href="/" multiple jasync />
<div type="file" href="/" multiple jasync>Выберите файл</div>
<div href="/" jasync dropfile>Перетащите файлы и они отправятся на сервер</div>
файлы загружаюся асинхронно

<a href="/" jasync data="year=2013&month=5" class="send">отправить данные</a>
данные отправляется ассинхронно

И тут у многих наверное возник вопрос, как обрабатывать полученные данные, если форма не валидна зачем её отправлять, а если я хочу ещё отправить дополнительные параметры?

И начнём с вопроса как обрабатывать полученные данные
$( '.send' ).bind( 'jasync.success', function( e, data ) {
	// data - обрабатываем данные
} );

Ну это же не интересно, таким образом мы много кода не сократим. Но иногда полезно.

И тут нам поможет скрипт jquery.message.async.js, нам только нужно с сервера посылать данные в определённом формате. И атрибут jasync=«message»
<form action="/" jasync="message">
	<input type="submit" />
</form>

Пример отправляемых данных:
{
	messages: {
		{
			type: 'replace',
			elem: '#myElem',
			html: 'Заменяем новым элементом'
		},
		{
			type: 'append',
			elem: '.myClass',
			html: 'Добавляем элементы'
		},
		{
			type: 'delete',
			elem: '.delElems'
		},
		{
			callback: 'alert',
			callback_params: [ 'Заработало' ]
		},
		{
			type: 'openPopap', // Реализацию в jquery.message.ajax.js надо вам дописать, поскольку попапы обычно у всех разные
			html: '...'
		}
	}
}

или

{
	url: 'Перейи по данному адресу'
}

И так в большинстве случаев мы можем не писать ajax запросы.

Дополнительно мы можем отменять отправку, например если форма не валидна:
$( 'form' ).bind( 'jasync.beforeSend', function( ) {
	var form = $( this );
	if( !form.isValid() ) {
		form.jasync( 'stop', true ); //Отменяем отправку
	}

	// Добавить дополнительные данные при отправке и поставить тип присылаемых данных
	form.jasync( {
		'addData': {
			count: 20,
			typesend: 'send jasync'
		},
		'dataType': 'json' // Тип возвращаемых данных
	} );
} );

Код на php будет выглядеть примерно так:
header( 'Content-type: text/json' );

echo json_encode( array(
	'messages' => array(
		array(
			'type' => 'replace',
			'elem' => '#myElem',
			'html' => 'Заменяем новым элементом'
		),
		array(
			'type' => 'append',
			'elem' => '.myClass',
			'html' => 'Добавляем элементы'
		),
		array(
			'type' => 'delete',
			'elem' => '.delElems'
		),
		array(
			'callback' => 'alert',
			'callback_params' => array('Заработало')
		)
	)
) );

Попробуем его улучшить, для этого напишем дополнительный класс AsyncResponse
$message = AsyncResponse::getInstance();
$message
	->add( AsyncResponse::REPLACE, '#myElem', 'Заменяем новым элементом' )
	->add( AsyncResponse::APPEND, '.myClass', 'Добавляем элементы' )
	->add( AsyncResponse::DELETE, '.delElems' )
	->addCallback( 'console.log', 'Заработало', '!!!' );
	//->openPopup( 'Контент' )

$message->end();


Будьте аккуратны когда данные у вас отсылаются через через iframe, это происходит в случаях:

  1. Когда вы отправляете запросы на другой домен.
    Поскольку в целях безопасности мы не можете прочитать данные из другого домена загруженного в iframe,
    вам необходимо при ответе сделать редирект на ваш домен, а там уже сформировать ответ.
  2. Когда у вас загружаются изображения в старых браузерах в которых нет поддержки FormData
    Также при отправке через iframe если у вас в ответе будут теги (например div),
    у вас возникнут проблемы, браузер добавит лишние закрывающие теги и распарсить json не получится.
    В данном случае отправляйте элементарные ответы без тегов, либо перед отправкой и при приёме замените кавычки


Загрузку файлов



image
В случае Drag and Drop будет работать только в браузерах поддерживающих Drag and Drop.

Сделаем ссылку при клике на которую будет появлятся окно с выбором файлов
<a href="/image/save/" name="image" multiple jasync>Выберите файлы</a>

или блок куда надо перетащить изображение
<div href="/image/save/" name="image" dropfile jasync>Перетащите файлы</div>

Подписываемся на события загрузки каждого изображения

$( document ).on( 'jasync.beforeSend', 'a[type=file]', function( e, imgs ) {
	// Добавляем данные для отправки
	$( this ).jasync( {
		'addData': {
			count: 20
		},
		'maxSize': 20000 // Максимальный размер файлов
	} );

	if( imgs.nosupport ) {
		$( '#answer' ).html( 'Идёт загрузка через iframe, нет поддержки пред отображения...' );
		return;
	}
                
	for( var i = 0, l = imgs.length; i < l; i++ ) {
		imgs[ i ]
			// Происходит когда файл готов для отображения
			.bind( 'jasync.load', function( e, file ) {
				// file - файл в формате base64
				$( 'body' ).append( '<img src="' + file + '" />' );

 				$( this )
					// Подписываемся на события процесса загрузки
					.bind( 'jasync.uploadProgress', function( e, percent, obj ) {
						// percent - процент загрузки
					} )
					// Событие успешной загрузки
					.bind( 'jasync.success', function( e, data ) {
						//console.log( data );
					} )
					// Произошла ошибка
					.bind( 'jasync.error', function() {
						
					} );
			} );
	}

} ).on( 'jasync.success', 'a[type=file]', function( e, data ) {
	// Ловим ответ при загрузке через iframe
	$( '#answer' ).html( data );
} );


Скачать скрипты можно по адресу http://jquery-async.com/download/
Или если сервер будет не доступен, что вполне возможно, то здесь
Теги:
Хабы:
Всего голосов 41: ↑27 и ↓14+13
Комментарии19

Публикации

Истории

Работа

Ближайшие события

Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область