Вы можете авторизоваться через ВКонтакте, Фейсбук и оставить комментарий


Загрузка изображений без перезагрузки страницы

Вступление

Почти все сайты сейчас в первую очередь направлены на производительность и удобный пользовательский интерфейс. Загрузка изображений без перезагрузки страницы одно из таких удобств.

Пример загрузки файлов без перезагрузки + готовый архив с примером для скачивания.

Пример ниже реализован на PHP+Ajax.

Понадобится

PHP, JavaScript и iframe. А так же 5 файлов: index.php, ajax.js, upload.js, upload.php, list.php и папка для загрузки изображений, в данном примере ./img/

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
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>AJAX-загрузка изображений без перезагрузки страницы</title>
<style type="text/css">
h1 {font-weight:normal; font-family:Georgia, serif; font-size:20pt;}
iframe {width:0; height:0; border:0;}
hr {clear:both; border:0; background-color:#CCC; height:1px;}
</style>
<script type="text/javascript" src="ajax.js"></script>
<script type="text/javascript" src="upload.js"></script>
</head>

<body onLoad="Upload.updateImagesList();">

<form onsubmit="return Upload.upload()"
      method="post" action="./upload.php" enctype="multipart/form-data"
      id="upload_image_form" target="upload_image_iframe">
    
    
    <input type="hidden" name="MAX_FILE_SIZE" value="512000">
    <h1>Загрузка изображений без перезагрузки страницы</h1>
    <p>Выберите файл с JPEG-изображением, не более 500Кб</p>
    <p><input type="file" name="image" id="upload_image_file"></p>
    <p><input type="submit" value="Загрузить изображение" id="upload_image_submit"></p>
</form><hr>

<p><a href="./clear.php">Удалить изображения</a></p>
<div id="layer_images_list">Нет изображений</div>

<iframe name="upload_image_iframe" id="upload_image_iframe"></iframe>

</body></html>

ajax.js

Данные файла упоминался в статье Как правильно послать запрос (Ajax).

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
/**
 * Класс для отправки асинхронных запросов, AJAX
 *
 * Автор: Федоров Артем
 * Сайт: http://artemfedorov.ru
 *
 */

Ajax = function(url, method, vars, encoding, callback, responsetype)
{
    this.xmlHttpRequest = null;

    this.ajax = this;
    this.buffer = null;
    
    this.url = url || false;
    this.method = method || 'GET';
    this.vars = vars || null;
    this.encoding = encoding || 'utf-8';
    this.onReady = callback || null;
    this.responseType = responsetype || 'xml';
    
    /**
     * type of return
     *
     */

    this.setResponseType = function(type)
    {
        this.responseType = type;
    }
    
    
    /**
     * To set url for ajax connection
     *
     */

    this.setUrl = function(url)
    {
        this.url = url;
    }
    
    
    /**
     * Set method: POST|GET
     *
     */

    this.setMethod = function(method)
    {
        this.method = method;
    }


    /**
     * Set vars
     *
     */

    this.setVars = function(vars)
    {
        this.vars = vars;
    }


    /**
     * Set encoding
     *
     */

    this.setEncoding = function(encoding)
    {
        this.encoding = encoding;
    }
    
    
    /**
     * Check for errors
     *
     */

    this.isError = function()
    {
        return false;
    }

    
    /**
     * Try to set url connection
     *
     */

    this.connect = function()
    {
        var url = this.url;
        var method = this.method;
        var vars = this.vars;
        var encoding = this.encoding;
        
        if (this.xmlHttpRequest != null)
        {
            this.xmlHttpRequest.open(method, url, true);
            this.xmlHttpRequest.onreadystatechange = function(ajax)
            {
                return function()
                {
                    ajax._progressResponse(ajax.xmlHttpRequest, ajax.responseType);
                }
            } (this);
            
            this.xmlHttpRequest.setRequestHeader("Content-Type""application/x-www-form-urlencoded; charset-"+encoding);
            this.xmlHttpRequest.send(vars);
        }
    }


    /**
     * To progress response to url
     *
     */

    this._progressResponse = function(xmlhttprequest, responsetype)
    {
        var value;
        if ( xmlhttprequest.readyState == 4 )
        {
            if (xmlhttprequest.status == 200 && this.onReady != null)
            {
                switch (responsetype)
                {
                    case 'text':
                        value = xmlhttprequest.responseText;
                        break;
                    
                    case 'xml':
                    default:
                        value = xmlhttprequest.responseXML;
                        break;
                    
                }
                
                this.onReady(value);
            }
            else
            {
                if (this.onReady == null)
                {
                    alert('Не определена функция Ajax.onReady');
                }
            }
        }
    }
    
    
    /**
     * Create http request
     *
     */

    this._createXmlHttpRequest = function()
    {
        if (window.XMLHttpRequest)
        {
            this.xmlHttpRequest = new XMLHttpRequest();
            if (this.xmlHttpRequest.overrideMimeType)
            {
                this.xmlHttpRequest.overrideMimeType('text/xml');
            }
        }
        else if (window.ActiveXObject)
        {
            try    {this.xmlHttpRequest = new ActiveXObject("Msxml2.XMLHTTP");}
            catch(e)
            {
                try    {this.xmlHttpRequest = new ActiveXObject("Microsoft.XMLHTTP");}
                catch(e){;}
            }
        }
    }


    this._createXmlHttpRequest();
}

upload.js

Файл начинает загрузку изображения и проверяет по таймеру статус загрузки изображения.

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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/**
 * Объект для загрузки изображений без перезагрузки страницы
 *
 * Автор: Федоров Артем
 * Сайт: http://artemfedorov.ru
 *
 */

var Upload = {
    isInit: false,
    
    error: '',
    
    iframe: null,
    imagesListLayer: null,
    
    inputFile: null,
    form: null,
    
    opts: {
        timeout: null,
        start: false,
        iframe: null,
        loaderImage: null
    },
    
    
    // инициализация основных опций
    init: function()
    {
        if (!this.isInit)
        {
            this.isInit = true;
            
            this.imagesListLayer = document.getElementById('layer_images_list');
            this.inputFile = document.getElementById('upload_image_file');
            this.form = document.getElementById('upload_image_form');
        }
    },
    
    // обновление списка изображений
    updateImagesList: function()
    {
        this.init();
        
        var ajax = new Ajax();
        ajax.setUrl('./list.php');
        ajax.setMethod('GET');
        
        ajax.onReady = function(upload)
        {
            return function(xml)
            {
                upload.xmlParseImages(xml);
            }
        }(this);
        
        ajax.connect();
    },
    
    // Калбак функция для обработки XML (обработка списка изображений)
    xmlParseImages: function(xml)
    {
        var i, a, img, images, image, img, divBg;
        
        images = xml.getElementsByTagName('image');
        
        this.imagesListLayer.innerHTML = images.length == 0 ? 'Изображений нет' : '';
        
        for (i=0; i<images.length; i++)
        {
            var img = new Image();
            img.align = 'left';
            img.height = 200;
            img.src = images[i].getAttribute('src');
            
            this.imagesListLayer.appendChild(img);
        }
    },
    
    // Загрузить изображение
    upload: function()
    {
        this.init();
        
        var status='', p;
        
        if (this.inputFile.value == ''this.error += "Вы не выбрали файл\r\n";
        if (/\.(jpg|jpeg)/i.test(this.inputFile.value) != truethis.error += "Файл должен иметь расширение .jpg или .jpeg\r\n";
        
        if (this.error != '')
        {
            alert(this.error);
            this.error = '';
            return false;
        }
        else
        {
            this.error = '';
        }
        
        if (!this.opts.start)
        {
            this.opts.start = true;
            this.opts.iframe = document.getElementById('upload_image_iframe');
        }
        
        status = this.checkUploadStatus();
        switch (status)
        {
            case '0':
                this.resetUpload();
                this.updateImagesList();
                return true;
                break;
                
            case 'NULL'case '1'case '2':
                this.error += "Файл превысил 500Кб\r\n";
                alert(this.error);
                this.resetUpload();
                break;
                
            case '3'case '4':
                this.error += 'Файл не был загружен\r\n';
                alert(this.error);
                this.resetUpload();
                break;
            
            case '5':
                this.error = 'Файл должен быть JPG\r\n';
                alert(this.error);
                this.resetUpload();
                break;
            
            default:
                document.getElementById('upload_image_submit').disabled = true;
                document.getElementById('upload_image_submit').value = 'Подождите, идет загрузка...';
                
                this.opts.timeout = setTimeout(function(upload)
                {
                    return function()
                    {
                        return upload.upload();
                    }
                }(this), 100);
                break;
        }
    },
    
    // Проверка статуса загрузки изображения
    checkUploadStatus: function()
    {
        return this.opts.iframe.contentWindow.document.body.innerHTML;
    },
    
    
    // Обновить форму загрузки изображений
    resetUpload: function()
    {
        this.error = '';
        
        clearTimeout(this.opts.timeout);
        this.opts.iframe.contentWindow.document.body.innerHTML = '';
        this.opts.start = false;
        this.form.reset();
        document.getElementById('upload_image_submit').disabled = false;
        document.getElementById('upload_image_submit').value = 'Загрузить изображение';
    }
}

upload.php — файл загрузки изображения

Принимает запрос на загрузку изображения и выводит на экран 0 — если файл успешно загружен, 1,2 — если размер файла превысил допустимый лимит, 3,4 если произошла какая-то другая ошибка, 5 — файл не является JPEG.

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
<?php

if (isset($_FILES['image']))
{
    if (
$_FILES['image']['type']!='image/jpg'&&$_FILES['image']['type']!='image/jpeg'&&$_FILES['image']['type']!='image/pjpeg')
    {
        echo 
'3';
    }
    elseif (
$_FILES['image']['error'] == 0)
    {
        
$filename './img/'.md5(uniqid(rand(), true)).'.jpg';
        
        while (
file_exists($filename))
        {
            
$filename './img/'.md5(uniqid(rand(), true)).'.jpg';
        }
        
        
move_uploaded_file($_FILES['image']['tmp_name'], $filename);
        echo 
'0';
    }
    else
    {
        echo 
$_FILES['image']['error'];
    }
}
else
{
    echo 
'2';
}

?>

list.php — список изображений

Файл генерирует XML-документ, который содержит список изображений, загруженных в папку ./img/.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?php

header
('Content-type: text/xml; charset=utf-8;');

echo 
'<?xml version="1.0" encoding="utf-8"?><images>';

$images scandir('./img/');
foreach (
$images as $image)
{
    if (
$image != '.' && $image != '..') echo '<image src="img/'.$image.'" />';
}

echo 
'</images>';

?>

Как это работает

POST-запрос на загрузку файла(upload.php), отправляется в скрытый iframe, где и будет выведен результат загрузки. После чего javascript-функция Upload.upload() по таймеру начинает проверку содержимого скрытого ифрейма.

upload.php может вывести 5 результатов: 0 — файл успешно загружен, 1,2 — если размер файла превысил допустимый лимит, 3,4 если произошла какая-то другая ошибка, 5 — файл не является JPEG.

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

Заключение

Многие называют это AJAX-загрузкой файлов, но на самом деле было бы правильней сказать — iframe-загрузка, т.к. при помощи аякса только получается список изображений.

Советую еще раз посмотреть пример работы или скачать готовый архив с примером.

Опубликовано: 09 апреля 2011  ·  Автор: Артём Фёдоров  ·  6618 просмотров

Категория

ГлавнаяПрограммированиеJavaScriptAjaxЗагрузка изображений без перезагрузки страницы

Чтобы оставить комментарий нужно авторизоваться на сайте
или войти через ВКонтакте или Фейсбук

Войти через ФейсбукВойти через Твиттер

Комментарии

Каким образом можно реализовать полосу загрузки файла?
Владислав Омельчук · 3 года назад
Добрый день!
А что нужно изменить, чтобы под каждой картинкой появлялось "удалить", то есть чтобы можно было удалять по одной картинке а не все сразу?
Никита Пушкарь · 3 года назад
Ajax, JavaScript, Программирование

© 2010-2016 expange.ru
При полном или частичном копировании статей сайта, ссылка на источник обязательна.

Хотите узнать больше информации, пишите на: artem@expange.ru

Полезное онлайн  ·  Новости  ·  Изображения  ·  Статьи по датам

О проекте  ·  Правила пользования  ·  Представительства

Благодарности и пожелания