За последние 24 часа нас посетили 16708 программистов и 1595 роботов. Сейчас ищет 1371 программист ...

Как передать файл c помощью AJAX

Тема в разделе "JavaScript и AJAX", создана пользователем виталий032, 3 дек 2017.

  1. виталий032

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

    С нами с:
    31 янв 2014
    Сообщения:
    227
    Симпатии:
    30
    Адрес:
    Владивосток
    Всем привет.
    Хочу отправить текстовый файл/картинку с помощью AJAX.
    С помощью интерфейса FormData всё собрать получается без проблем, а без него - надо вручную вбивать содержимое файла в заголовки.
    Делаю, как написано здесь https://learn.javascript.ru/xhr-forms

    Вопрос в том, как поместить содержимое загруженного файла в заголовки (а, если это будет картинка)?

    Если вставляю содержимое вот так, upload_file.files[0], вместо 'Наконец-то', то в сохраняемом файле сохраняется [Object].

    HTML:
    1. <input type="file" id="file" multiple><br>
    2.     <button type="submit" id="upload">Upload</button>
    Код (Javascript):
    1. var btn = document.getElementById('upload');
    2.     var upload_file = document.getElementById('file');
    3.  
    4.     btn.onclick = function () {
    5.         // console.log(upload_file.files[0]);
    6.  
    7.         var data = {
    8.           name: 'Виктор',
    9.           surname: 'Цой'
    10.         };
    11.  
    12.         var boundary = String(Math.random()).slice(2);
    13.         var boundaryMiddle = '--' + boundary + '\r\n';
    14.         var boundaryLast = '--' + boundary + '--\r\n'
    15.  
    16.         var body = ['\r\n'];
    17.         for (var key in data) {
    18.           // добавление поля
    19.           body.push('Content-Disposition: form-data; name="' + key + '"\r\n\r\n' + data[key] + '\r\n');
    20.         }
    21.  
    22.         body.push('Content-Disposition: form-data; name="myfile"; filename="test.txt"' + '\r\n' +
    23.             'Content-Type: text/plain\r\n\r\n' +
    24.             'Наконец-то!' +
    25.             '\r\n');
    26.  
    27.         body = body.join(boundaryMiddle) + boundaryLast;
    28.  
    29.         console.log(body);
    30.  
    31.         // Тело запроса готово, отправляем
    32.  
    33.         var xhr = new XMLHttpRequest();
    34.         xhr.open('POST', '/upload.php', true);
    35.  
    36.         xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
    37.  
    38.         xhr.onreadystatechange = function() {
    39.           if (this.readyState != 4) return;
    40.  
    41.           alert( this.responseText );
    42.         }
    43.  
    44.         xhr.send(body);
    45.     }
     
  2. Fell-x27

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

    С нами с:
    25 июл 2013
    Сообщения:
    12.156
    Симпатии:
    1.770
    Адрес:
    :сердА
    Вот тут можно подробнее?
    --- Добавлено ---
    Да, небольшие файлы можно гонять через base64 без заморочек.
     
  3. виталий032

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

    С нами с:
    31 янв 2014
    Сообщения:
    227
    Симпатии:
    30
    Адрес:
    Владивосток
    Проблема решена!
    Заместо слово "содержимое", что ниже, должно быть содержимое файла, которое мы выбрали на клиенте, но не отправили на сервер!

    Код (Text):
    1. --6812748192417928
    2. Content-Disposition: form-data; name="myfile"; filename="test.txt"
    3. Content-Type: text/plain
    4.  
    5. содержимое
    Потанцевал с бубном и сделал вот так (всё работает) :
    Код (Javascript):
    1. var btn = document.getElementById('upload');
    2. var upload_file = document.getElementById('file');
    3.  
    4.     btn.onclick = function () {
    5.         var reader = new FileReader();
    6.         reader.readAsText(upload_file.files[0]);
    7.  
    8.         reader.onloadend = function () {
    9.             alert(reader.result);
    10.             send(reader.result);
    11.         }
    12.     }
    13.  
    14.     function send(file_content)
    15.     {
    16.         var data = {
    17.           name: 'Виктор',
    18.           surname: 'Цой'
    19.         };
    20.  
    21.         var boundary = String(Math.random()).slice(2);
    22.         var boundaryMiddle = '--' + boundary + '\r\n';
    23.         var boundaryLast = '--' + boundary + '--\r\n';
    24.  
    25.         var body = ['\r\n'];
    26.         for (var key in data) {
    27.           // добавление поля
    28.           body.push('Content-Disposition: form-data; name="' + key + '"\r\n\r\n' + data[key] + '\r\n');
    29.         }
    30.  
    31.         body.push('Content-Disposition: form-data; name="myfile"; filename="test.txt"' + '\r\n' +
    32.             'Content-Type: text/plain\r\n\r\n' +
    33.             file_content +
    34.             '\r\n');
    35.  
    36.         body = body.join(boundaryMiddle) + boundaryLast;
    37.  
    38.         console.log(body);
    39.  
    40.         // Тело запроса готово, отправляем
    41.  
    42.         var xhr = new XMLHttpRequest();
    43.         xhr.open('POST', '/submit.php', true);
    44.  
    45.         xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
    46.  
    47.         xhr.onreadystatechange = function() {
    48.           if (this.readyState != 4) return;
    49.  
    50.           alert( this.responseText );
    51.         }
    52.  
    53.         xhr.send(body);
    54.     }
     
  4. MouseZver

    MouseZver Суперстар

    С нами с:
    1 апр 2013
    Сообщения:
    7.798
    Симпатии:
    1.331
    Адрес:
    Лень
    человечек не стал заморачиваться и пошел по низкоуровневому кодингу
     
    виталий032 нравится это.