AJAX 提交带有文件上传的表单。

21 浏览
0 Comments

AJAX 提交带有文件上传的表单。

我正在使用jQuery和Ajax来提交数据和文件,但我不确定如何在一个表单中同时发送数据和文件。

目前我用两种方法几乎完全相同,但数据收集到数组中的方式不同,数据使用.serialize();,而文件使用= new FormData($(this)[0]);

是否可能将两种方法结合起来,通过Ajax在一个表单中上传文件和数据?

Data 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;
});

Files 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;
});

如何将上述内容组合在一起,以便我可以通过Ajax在一个表单中发送数据和文件?

我的目标是能够通过一个post请求将整个表单发送,这是可能的吗?

0
0 Comments

AJAX提交带有文件上传的表单的问题出现的原因是无法直接使用AJAX提交包含文件的表单。解决方法是使用iframe,并将表单的目标设置为该iframe。

下面是一个使用jQuery的示例代码:

function ajax_form($form, on_complete)
{
    var iframe;
    if (!$form.attr('target'))
    {
        //为表单创建一个唯一的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 ()
        {
            //获取服务器响应
            var response = iframe.contents().find('body').text();
            on_complete(response);
        });
    }
}

这种方法在所有浏览器上都可以正常工作,不需要对数据进行序列化或准备。缺点是无法监控进度。另外,至少对于Chrome浏览器来说,请求不会出现在开发者工具的“xhr”选项卡下,而是在“doc”选项卡下。

虽然这种方法实际上不是使用AJAX,但对于有同样问题的人来说仍然有用。

0
0 Comments

问题原因:使用了错误的jQuery标识符。

解决方法:使用正确的jQuery标识符。

在使用AJAX进行文件上传时,可以使用一个表单同时上传数据和文件。

使用PHP + HTML实现:


使用jQuery + Ajax实现:

$("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);
    });
});

以上方法能正常工作,但我需要在响应中显示"文件上传成功,感谢上传",但是我得到的响应中有<br/>标签,如何解决这个问题?

不要使用Internet Explorer?......说真的,我不知道,我很确定它对我有效,尝试更详细地调试问题,什么不能正常工作?为什么你有两个账户?

在IE 8或9中,这个解决方案将不起作用,因为FormData是一个HTML5对象,不在IE 8或9中存在。

如何在没有form的情况下获取文件?

$(this)[0]只是this的别名,所以new FormData(this)就足够了。

似乎无法检查FormData对象,请参考这个问题(对于任何遇到与我一样无能为力的人,因为该对象始终为空)。

对于将来的读者:contentType和processData声明很重要。更多信息请参见这个答案

我尝试了你答案中的简洁方法,但对我来说似乎没有起作用。然而,使用async : false的长版本起作用了。-------我在使用文件://和canJS的can.fixture()模拟post终点。

在移动端(单线程)浏览器上,不需要async: false,它会导致阻塞。

你知道后端开发人员如何从这个请求中获取表单文件和表单数据吗?

cache选项似乎不是必需的。简洁版本对我不起作用。

IE<10有没有回退解决方案?

在我的情况下,我必须使用contentType: "application/octet-stream"

- 那会破坏一些东西。你需要contentType: false

- 不完全是这样。唯一的方法是使用隐藏的iframe技巧。......但是这些浏览器多年来没有接收到任何安全更新,并且它们的市场份额很小。

- 与任何普通的多部分表单提交相同。具体细节取决于编程语言和表单处理库。

我确实最终使用了contentType: false,同时在服务器端也使用了文件输入上的name属性。

我使用这个解决方案,但似乎表单只提交了文件而没有提交中的值,有什么建议可以查看吗?

请注意,较短的版本可能会出现非法调用的问题,你可能需要设置contentTypeprocessData,就像较长的版本一样。

0
0 Comments

在ASP.Net MVC中,我遇到了使用HttpPostedFileBase上传文件的问题。我需要在按钮点击时执行一些操作,然后如果一切正常再提交表单。下面是我解决这个问题的方法:

$(".submitbtn").on("click", function(e) {
    var form = $("#Form");
    var formData = new FormData(form[0]);
    
    if ($(form).valid()) {
        $.ajax({
            type: "POST",
            url: $(form).prop("action"),
            data: formData,
            contentType: false,
            processData: false,
            error: ErrorHandler,
            success: successHandler
        });
    }
});

以上代码会正确地填充我的MVC模型,请确保在模型中,HttpPostedFileBase[]属性的名称与HTML中的输入控件的名称相同,例如:


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

在我的情况下,我需要使用contentType : "application/octet-stream"

非常感谢你,你节省了我很多时间。

0