Ninazu
@Ninazu

Ajax multipart/form-data без JQuery почему не работает?

Собственно задача такая. Отправлять через Ajax форму с типом multipart/form-data, без использования jQuery. В форме находятся инпуты с файлами и пару полей. В конечном итоге Header'ы получается аналогичный.
Вот этот заголовок формируется через jQuery
846afe5c5044a15fda31197976d3a38a.png
А этот отправляю я
ded447576df0867ac1d40c40798eb40d.png

На сервере первый приходит с $_POST, во втором случае $_POST пустой. В чем причина понять не могу. Ведь отличие только в boundary (что в принципе и правильно)

Ну и на всякий случай код генерации аякса
generateBoundary = function() {
            var MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split('');
            var buffer='';
            for(var i = 1; i < 17; i++) {
                var rand=(Math.random() * (MULTIPART_CHARS.length - 0) + 0)| 0;
                buffer+=(MULTIPART_CHARS[rand]);
            }
            return buffer;
        };
ajax = function ($obj) {
            if(typeof $obj.type=='undefined') $obj.type="GET";
            if(typeof $obj.data=='undefined') $obj.data=null;
            var xmlhttp;var datax;
            if (window.XMLHttpRequest) xmlhttp=new XMLHttpRequest();
            else  xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
            xmlhttp.open($obj.type,$obj.url,true);
            datax=$obj.data;
            if($obj.data!=null){
                if($obj.type=="POST") {
                    var boundary=Math.random().toString().substr(2);
                    boundary="----WebKitFormBoundary"+generateBoundary();
                    xmlhttp.setRequestHeader('Content-Type', 'multipart/form-data; boundary='+boundary );
                    var formData = new FormData();
                    var key; var attr;
                    for(key in $obj.files) {
                        if ($obj.files.hasOwnProperty(key)) {
                            attr = $obj.files[key];
                            formData.append(key, attr, attr.name);
                        }
                    }
                    for(key in $obj.data) {
                        if ($obj.data.hasOwnProperty(key)) {
                            attr = $obj.data[key];
                            console.log(key,"=>", attr);
                            formData.append('file-'+key, attr);
                        }
                    }
                    datax=formData;
                }else{
                    datax=this.serialize($obj.data);
                }
            }
            xmlhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            var csrf=document.getElementsByName('csrf-token')[0];
            if(csrf){
                xmlhttp.setRequestHeader('X-CSRF-Token', csrf.getAttribute("content"));
            }
            xmlhttp.onreadystatechange=function() {
                if (xmlhttp.readyState==4){
                    switch (xmlhttp.status) {
                        case 200:
                            if(typeof $obj.success=='function'){
                                $obj.success(xmlhttp.responseText);
                            }

                            break;
                        default:
                            break;

                    }
                }
            };
            xmlhttp.send(datax);
        };
  • Вопрос задан
  • 7975 просмотров
Решения вопроса 1
Sanasol
@Sanasol Куратор тега JavaScript
нельзя просто так взять и загуглить ошибку
посмотрите Content-Type
разные Boundary
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
Вот простой код на jquery, думаю адаптировать под свой проект сможете
upload.on('change', function(){
        var data = new FormData();
        data.append('file', uploadButton[0].files[0]);

        $.ajax({
            url: '/url/upload.php',
            type: 'POST',
            data: data,
            processData: false,
            contentType: false,
            dataType: 'json',
            success: function(result) {
                
            },
            error: function (result) {
                
            }
        });
    });

В обработчике обрабатываете все стандартно
Ответ написан
mlnkv
@mlnkv
JavaScript Developer
var MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".split("");

function generateBoundary() {
  var buffer = "";
  for(var i = 1; i < 17; i++) {
    buffer += (MULTIPART_CHARS[(Math.random() * (MULTIPART_CHARS.length - 0) + 0) | 0]);
  }
  return buffer;
};

function ajax(params) {
  var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
  params.type = params.type || "GET";
  params.data = params.data || null;  

  xhr.open(params.type, params.url, true);

  if (params.data) {    
    if (params.type == "POST") {
      xhr.setRequestHeader("Content-Type", "multipart/form-data; boundary=" + "----WebKitFormBoundary" + generateBoundary());
      var formData = new FormData();
      var key;
      var attr;
      for (key in params.files) {
        if (params.files.hasOwnProperty(key)) {
          attr = params.files[key];
          formData.append(key, attr, attr.name);
        }
      }
      for(key in params.data) {
        if (params.data.hasOwnProperty(key)) {
          attr = params.data[key];
          console.log(key, "=>", attr);
          formData.append('file-'+key, attr);
        }
      }
      params.data = formData;
    }else{
      params.data = this.serialize(params.data);
    }
  }

  xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
  var csrf = document.getElementsByName('csrf-token')[0];
  if (csrf) {
    xhr.setRequestHeader('X-CSRF-Token', csrf.getAttribute("content"));
  }
  xhr.onreadystatechange = function() {
    if (xhr.readyState == 4 && xhr.status == 200) {
      params.success && params.success(xhr.responseText);
    }
  };

  xhr.send(params.data);
};
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы