如何正确发送带有文本和文件输入字段的表单数据?

时间:2014-01-26 21:51:40

标签: jquery ajax forms node.js post

我在发送包含文本和文件字段的表单时遇到问题。我可以选择:

1)发送包含指定字段的自定义请求

$("#form_new_product").submit(function(event){
event.preventDefault();
    if ( product_name ) { 
        $.post( 
            '/product/create',
            { product_name: product_name,
              product_description: product_description
              // file : file ???
            })  
        .fail(function(res){
            alert("Error: " + res.getResponseHeader("error"));
            })  
        .done(function(res){
            showInfoAlert("Product : \"" + product_name + "\" has been added to catalog.");
            }); 
    }
}

但是这样我就无法指定要上传的文件(file.path) - 这是通过POST请求的files字段传递的内容(任何想法怎么做?)

2)发布“普通”/非自定义表单字段,但我不知道如何使用jquery中的ajax (使用上面的代码段showInfoAlert和{{ 1}}表示响应状态)

3 个答案:

答案 0 :(得分:2)

处理这个的一个很好的方法,因为你还在使用jQuery,是jQuery Form插件:http://malsup.com/jquery/form/。它被广泛使用,没有任何重大错误,就像我见过的那样(已经使用了好几个月),易于实现。

答案 1 :(得分:0)

首先,确保正确命名表单输入,这将使您的生活更轻松                                 

如果您不希望支持IE8 / 9上传ajax,可以使用以下内容:

// FormData is not supported by ie8 and 9 as far as I know
// and some others see here: http://caniuse.com/#search=FormData 
// you can check for FormData support by something like this
var supportFormData = function(){
    return !! window.FormData;
};

 $('#form_new_product').submit(function(e) {
    e.preventDefault();
    var form;

    // you can pass in your form element here if you have the <input> tags named correctly, like this:
    form = new FormData($("#form_new_product").eq(0)) // that's the easiest way

    // or you can create a FormData object and append stuff to it
    form = new FormData();
    // signature --> form.append(input[name], input[value])
    form.append('product_name', $('#form_new_product input[name="product_name"]').val());
    form.append('product_description', $('#form_new_productinput[name="product_description"]').val());
    // now a file input,
    form.append('product_image', $('#form_new_product input[type="file"]').eq(0).files[0], 'image.png'/*optional*/);

    return $.ajax({
        url: '/path/to/form/action',
        type: 'POST',
        data: form,
        mimeType:'multipart/form-data",
        contentType: false,
        cache: false,
        processData: false
    )
    .done(function(response){
       // handle success
    })
    .fail(function(response){
       // handle error
    });
});

如果你想支持IE8和IE9,你可能还需要做一些小的调整服务器端, 并且你的submitForm函数不会像上一个那样简单,我建议使用http://malsup.com/jquery/form/ 像其他一些答案一样,但正如插件所提到的,here 服务器响应头必须是text/html所以IE8不会触发JSON响应的文件下载(假设您期待JSON响应) - 基本上这个插件正在创建一个带有表单的iFrame并将其提交给服务器给你。除text/html之外还有其他解决方案,就像使用<textarea>包装响应一样,检查我提到的最后一个链接。

所以,假设你正在使用这个插件,我会这样做。

var isIE = function () {
    var myNav = navigator.userAgent.toLowerCase();
    return (myNav.indexOf('msie') != -1) ? parseInt(myNav.split('msie')[1]) : false;
}

$('#form_new_product').submit(function(e) {
    e.preventDefault();
    var $form = $("#form_new_product");

    var options = {
        url: '/path/to/form/action',
        type: "POST",
        mimeType: "multipart/form-data"
    };

    // hack because IE lt 9 iFrame triggers a file download for a application/json response
    // http://stackoverflow.com/questions/17701992/ie-iframe-doesnt-handle-application-json-response-properly
    if (Reporting.util.isIE() <= 9) {
        // maybe you have another contract with the server, like a custom query string or whatever
        // but the server needs to return text/html
        options.ContentType = "text/html";
    }

    // don't think this returns a promise, so you can use the options.success and options.error like that
    options.success = function(response){
      // handle success
    };
    options.error = function(response){
      // handle error
    };

    // or you really want to return a promise, then you can 
    var deferred = new $.Deferred();
    options.success(function(response){
        deferred.resolve(response);
    });
    options.error(function(response){
        deferred.reject(response);
    })

        // this will submit all of your inputs
    form.ajaxSubmit(options);
    return deferred;
});                                                                      

答案 2 :(得分:-1)

未经用户确认,您无法发送文件字段。 用户必须手动填写该字段。

如果你没问题,你可以阅读this page,它将解释如何做到这一点; - )