Pull to refresh

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

Reading time4 min
Views16K
Итак 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/
Или если сервер будет не доступен, что вполне возможно, то здесь
Tags:
Hubs:
Total votes 41: ↑27 and ↓14+13
Comments19

Articles