[javascript] Ajax를 사용하여 데이터와 파일을 모두 한 형태로 업로드 하시겠습니까?

양식에 데이터와 파일을 제출하기 위해 jQuery와 Ajax를 사용하고 있지만 한 양식으로 데이터와 파일을 모두 보내는 방법을 잘 모르겠습니까?

나는 현재 두 가지 방법으로 거의 동일하지만 데이터가 배열로 수집되는 방식은 다르지만 데이터는 사용 .serialize();하지만 파일은 사용합니다.= new FormData($(this)[0]);

Ajax를 통해 파일과 데이터를 한 형태로 업로드 할 수 있도록 두 방법을 결합 할 수 있습니까?

데이터 jQuery, Ajax 및 HTML

$("form#data").submit(function(){

    var formData = $(this).serialize();

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        async: false,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });

    return false;
});

<form id="data" method="post">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <button>Submit</button>
</form>

파일 jQuery, Ajax 및 html

$("form#files").submit(function(){

    var formData = new FormData($(this)[0]);

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        async: false,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });

    return false;
});

<form id="files" method="post" enctype="multipart/form-data">
    <input name="image" type="file" />
    <button>Submit</button>
</form>

Ajax를 통해 데이터와 파일을 한 형태로 보낼 수 있도록 위의 내용을 어떻게 결합 할 수 있습니까?

내 목표는이 모든 양식을 Ajax와 함께 한 게시물에 보낼 수 있도록하는 것입니다. 가능합니까?

<form id="datafiles" method="post" enctype="multipart/form-data">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <input name="image" type="file" />
    <button>Submit</button>
</form>



답변

내가 가진 문제는 잘못된 jQuery 식별자를 사용하고있었습니다.

ajax를 사용하여 하나의 양식으로 데이터와 파일업로드 할있습니다 .

PHP + HTML

<?php

print_r($_POST);
print_r($_FILES);
?>

<form id="data" method="post" enctype="multipart/form-data">
    <input type="text" name="first" value="Bob" />
    <input type="text" name="middle" value="James" />
    <input type="text" name="last" value="Smith" />
    <input name="image" type="file" />
    <button>Submit</button>
</form>

jQuery + 아약스

$("form#data").submit(function(e) {
    e.preventDefault();
    var formData = new FormData(this);

    $.ajax({
        url: window.location.pathname,
        type: 'POST',
        data: formData,
        success: function (data) {
            alert(data)
        },
        cache: false,
        contentType: false,
        processData: false
    });
});

짧은 버전

$("form#data").submit(function(e) {
    e.preventDefault();
    var formData = new FormData(this);

    $.post($(this).attr("action"), formData, function(data) {
        alert(data);
    });
});


답변

또 다른 옵션은 iframe을 사용하고 양식의 대상을 설정하는 것입니다.

당신은 이것을 시도 할 수 있습니다 (jQuery를 사용합니다) :

function ajax_form($form, on_complete)
{
    var iframe;

    if (!$form.attr('target'))
    {
        //create a unique iframe for the form
        iframe = $("<iframe></iframe>").attr('name', 'ajax_form_' + Math.floor(Math.random() * 999999)).hide().appendTo($('body'));
        $form.attr('target', iframe.attr('name'));
    }

    if (on_complete)
    {
        iframe = iframe || $('iframe[name="' + $form.attr('target') + '"]');
        iframe.load(function ()
        {
            //get the server response
            var response = iframe.contents().find('body').text();
            on_complete(response);
        });
    }
}

모든 브라우저에서 잘 작동하므로 데이터를 직렬화하거나 준비 할 필요가 없습니다. 한 가지 단점은 진행 상황을 모니터링 할 수 없다는 것입니다.

또한 Chrome의 경우 요청은 개발자 도구의 “xhr”탭이 아니라 “doc”아래에 나타납니다.


답변

ASP.Net MVC에서 HttpPostedFilebase를 사용하여 동일한 문제가 발생했으며 제출시 양식을 사용하는 대신 클릭해야 할 부분을 클릭해야했습니다.

$(".submitbtn").on("click", function(e) {

    var form = $("#Form");

    // you can't pass Jquery form it has to be javascript form object
    var formData = new FormData(form[0]);

    //if you only need to upload files then 
    //Grab the File upload control and append each file manually to FormData
    //var files = form.find("#fileupload")[0].files;

    //$.each(files, function() {
    //  var file = $(this);
    //  formData.append(file[0].name, file[0]);
    //});

    if ($(form).valid()) {
        $.ajax({
            type: "POST",
            url: $(form).prop("action"),
            //dataType: 'json', //not sure but works for me without this
            data: formData,
            contentType: false, //this is requireded please see answers above
            processData: false, //this is requireded please see answers above
            //cache: false, //not sure but works for me without this
            error   : ErrorHandler,
            success : successHandler
        });
    }
});

이 뜻이 제대로 MVC 모델을 채우는 것보다, 모델, HttpPostedFileBase의 속성 [에 있는지 확인하시기 바랍니다]를 같은 이름이 이름 html로 IE에서 입력 제어를

<input id="fileupload" type="file" name="UploadedFiles" multiple>

public class MyViewModel
{
    public HttpPostedFileBase[] UploadedFiles { get; set; }
}


답변

또는 더 짧게 :

$("form#data").submit(function() {
    var formData = new FormData(this);
    $.post($(this).attr("action"), formData, function() {
        // success    
    });
    return false;
});


답변

나를 위해, 그것은없이 작동하지 않았다 enctype: 'multipart/form-data' Ajax 요청에 필드 . 나는 그것이 비슷한 문제에 갇힌 누군가를 돕기를 바랍니다.

enctype 가 form 속성에 이미 설정되어 있지만 어떤 이유로 든 Ajax 요청이 enctype명시 적 선언없이 자동으로 식별하지 못했습니다 (jQuery 3.3.1).

// Tested, this works for me (jQuery 3.3.1)

fileUploadForm.submit(function (e) {
    e.preventDefault();
    $.ajax({
            type: 'POST',
            url: $(this).attr('action'),
            enctype: 'multipart/form-data',
            data: new FormData(this),
            processData: false,
            contentType: false,
            success: function (data) {
                console.log('Thank God it worked!');
            }
        }
    );
});

// enctype field was set in the form but Ajax request didn't set it by default.

<form action="process/file-upload" enctype="multipart/form-data" method="post" >

     <input type="file" name="input-file" accept="text/plain" required>
     ...
</form>

위에서 언급 한 다른 사람 contentTypeprocessData필드 에도 특별한주의를 기울이십시오 .


답변

나를 위해 코드 작업을 수행하십시오.

$(function () {
    debugger;
    document.getElementById("FormId").addEventListener("submit", function (e) {
        debugger;
        if (ValidDateFrom()) { // Check Validation 
            var form = e.target;
            if (form.getAttribute("enctype") === "multipart/form-data") {
                debugger;
                if (form.dataset.ajax) {
                    e.preventDefault();
                    e.stopImmediatePropagation();
                    var xhr = new XMLHttpRequest();
                    xhr.open(form.method, form.action);
                    xhr.onreadystatechange = function (result) {
                        debugger;
                        if (xhr.readyState == 4 && xhr.status == 200) {
                            debugger;
                            var responseData = JSON.parse(xhr.responseText);
                            SuccessMethod(responseData); // Redirect to your Success method 
                        }
                    };
                    xhr.send(new FormData(form));
                }
            }
        }
    }, true);
});

Action Post Method에서 매개 변수를 HttpPostedFileBase UploadFile로 전달하고 파일 입력이 Action Method의 매개 변수에서 언급 한 것과 동일한 지 확인하십시오. AJAX Begin 양식에서도 작동합니다.

위에서 언급 한 코드에 포스트 콜을 정의하고 요구 사항에 따라 코드에서 메소드를 참조 할 수 있으므로 AJAX BEGIN 양식은 여기에서 작동하지 않습니다.

나는 늦게 응답한다는 것을 알고 있지만 이것이 나를 위해 일한 것입니다.


답변

간단하지만보다 효과적인 방법
new FormData()은 컨테이너 (또는 가방)와 같습니다. 모든 속성이나 파일을 넣을 수 있습니다. attribute, file, fileName예 를 추가해야 할 유일한 것은 :

let formData = new FormData()
formData.append('input', input.files[0], input.files[0].name)

AJAX 요청으로 전달하십시오. 예 :

    let formData = new FormData()
    var d = $('#fileid')[0].files[0]

    formData.append('fileid', d);
    formData.append('inputname', value);

    $.ajax({
        url: '/yourroute',
        method: 'POST',
        contentType: false,
        processData: false,
        data: formData,
        success: function(res){
            console.log('successfully')
        },
        error: function(){
            console.log('error')
        }
    })

FormData를 사용하여 n 개의 파일 또는 데이터를 추가 할 수 있습니다.

그리고 Node.js에서 Script.js 파일에서 Route 파일로 AJAX 요청을하는 경우
req.body데이터 (예 : 텍스트)
req.files에 액세스하여 파일 (예 : 이미지, 비디오 등) 에 액세스하는 데 주의하십시오.