jquery-form/form

IE9 bad request body generation

odahcam opened this issue · 10 comments

Description:

Well, this is a very delicated issue, which I have no idea how to deal with.

I have a form where I work with complex data object generation. Like the following:

{
    "Id": 123564,
    "Nome": "Test, example name",
    "OtherFields": "Other fields values",
    "LaminaExposicaoComposicaoProdutos": [
        {
            "Id": 123456,
            "Nome": "Example name",
            "Codigo": "987456213"
        }, {
            "Id": 223456,
            "Nome": "Another Example name",
            "Codigo": "287456213"
        }
    ]
}

The object is that, but the request generated in IE9 differs a lot from IE10.

image

image

IE9 vs. IE10 request body

diff --git a/ie9/rq-body b/ie10/rq-body
index 0ea0aa5..b73a090 100644
--- a/ie9/rq-body
+++ b/ie10/rq-body
@@ -1,198 +1,253 @@
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Id"

 0
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="IdLaminaExposicao"

 2
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="IdUsuarioCadastro"

 0
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="IdUsuarioAlteracao"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="DataCadastro"

 01/01/0001 00:00:00
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="DataAlteracao"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Nome"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Situacao"

 Ativo
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="AnoSemanaEntregaInicial"

 2017
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="SemanaEntregaInicial"

 39
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="AnoSemanaEntregaFinal"

 2017
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="SemanaEntregaFinal"

 40
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Observacao"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Produto.Id"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Produto.Codigo"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Produto.Nome"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 29312
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 29313
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 29314
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 144414
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 144415
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 144419
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 144489
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 144494
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 144496
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 344600
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 344602
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[][IdProduto]"

 344606
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="OrdemCompra.Id"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="OrdemCompra.Codigo"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="LaminaExposicaoComposicaoOrdemCompras[][IdOrdemCompra]"

 531706
------------------------------7e113736f068a
-Content-Disposition: form-data; name="ImagemCapa"; filename=""
-Content-Type: application/octet-stream
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="ImagemCapa"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Id"

 0
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="IdLaminaExposicao"

 2
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="IdUsuarioCadastro"

 0
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="IdUsuarioAlteracao"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="DataCadastro"

 01/01/0001 00:00:00
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="DataAlteracao"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Nome"


------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Situacao"

 Ativo
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="AnoSemanaEntregaInicial"

 2017
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="SemanaEntregaInicial"

 39
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="AnoSemanaEntregaFinal"

 2017
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="SemanaEntregaFinal"

 40
------------------------------7e113736f068a
+-----------------------------7e129812f068a
 Content-Disposition: form-data; name="Observacao"


------------------------------7e113736f068a
-Content-Disposition: form-data; name="Produto"
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="Produto[Id]"

-[object Object]
------------------------------7e113736f068a
-Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos"

-[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
------------------------------7e113736f068a
-Content-Disposition: form-data; name="OrdemCompra"
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="Produto[Codigo]"

-[object Object]
------------------------------7e113736f068a
-Content-Disposition: form-data; name="LaminaExposicaoComposicaoOrdemCompras"

-[object Object]
------------------------------7e113736f068a--
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="Produto[Nome]"
+
+
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[0][IdProduto]"
+
+29312
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[1][IdProduto]"
+
+29313
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[2][IdProduto]"
+
+29314
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[3][IdProduto]"
+
+144414
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[4][IdProduto]"
+
+144415
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[5][IdProduto]"
+
+144419
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[6][IdProduto]"
+
+144489
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[7][IdProduto]"
+
+144494
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[8][IdProduto]"
+
+144496
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[9][IdProduto]"
+
+344600
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[10][IdProduto]"
+
+344602
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoProdutos[11][IdProduto]"
+
+344606
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="OrdemCompra[Id]"
+
+
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="OrdemCompra[Codigo]"
+
+
+-----------------------------7e129812f068a
+Content-Disposition: form-data; name="LaminaExposicaoComposicaoOrdemCompras[0][IdOrdemCompra]"
+
+531706
+-----------------------------7e129812f068a--
(END)

That's it!

Expected Behavior: I want to receive a multilevel object in my action endpoint. That object is not being generated in JS code.

Actual behavior: I'm receiving an single level object in my action endpoint. The multilevel object has only the first level well writed in the request body.

Versions:

LoadJSON: N/A
jQuery: any
Browsers: IE9

Demonstration

Can't reproduce in an online fiddler.

Steps to reproduce:

  1. Generate your multilevel object from the form data.
    1.1 I used a custom function, which could be implemented in this plugin.
  2. Send it via $('form').ajaxSubmit method.
  3. Ta-dam!

I will try to improve this issue description as long as I have more time to write. TA.

I tested submitting the form with the last @malsup version, the same problem occours.

Function used to serialize the form into a complex object:

/**
 * @example var model = $('form').serializeObjectComplex();
 *
 * Consider the form below:
 *
 * <form>
 *     <input name="Name" value="Hello" />
 *     <input name="Address[Street]" value= "No Name st." />
 *     <input name="ProductsModel[][Id]" value= "656" />
 *     <input name="ProductsModel[][Id]" value= "98741" />
 * </form>
 *
 * This form would be serialized to:
 * 
 * {
 *     Name: 'Hello',
 *     Address: {
 *         Street: "No Name st."
 *     },
 *     ProductsModel: [ // equivalent to a C# `List<ProductsModel>`
 *         { Id: 656 },
 *         { Id: 98741 },
 *     ]
 * }
 */
jQuery.fn.serializeObjectComplex = function () {

    var self = this,
        json = {},
        push_counters = {},
        patterns = {
            "validate": /^[a-zA-Z][a-zA-Z0-9_]*(?:\[(?:\d*|[a-zA-Z0-9_]+)\])*$/,
            "key": /[a-zA-Z0-9_]+|(?=\[\])/g,
            "push": /^$/,
            "fixed": /^\d+$/,
            "named": /^[a-zA-Z0-9_]+$/
        };


    this.build = function (base, key, value) {
        base[key] = value;
        return base;
    };

    this.push_counter = function (key) {
        if (push_counters[key] === undefined) {
            push_counters[key] = 0;
        }
        return push_counters[key]++;
    };

    $.each($(this).serializeArray(), function () {

        /*
        // skip invalid keys
        if (!patterns.validate.test(this.name)) {
            console.log(this.name)
            return;
        }
        */

        var k,
            keys = this.name.match(patterns.key),
            merge = this.value,
            reverse_key = this.name;

        while ((k = keys.pop()) !== undefined) {

            // adjust reverse_key
            reverse_key = reverse_key.replace(new RegExp("\\[" + k + "\\]$"), '');

            // push
            if (k.match(patterns.push)) {
                merge = self.build([], self.push_counter(reverse_key), merge);
            }

                // fixed
            else if (k.match(patterns.fixed)) {
                merge = self.build([], k, merge);
            }

                // named
            else if (k.match(patterns.named)) {
                merge = self.build({}, k, merge);
            }
        }

        json = $.extend(true, json, merge);
    });

    return json;
};

Considering how significantly different the JS engine is in IE 9, I suspect that your problem is there. On the other hand, since you've already serialized the form, it's also possible jQuery Form is re-serializing your data.

If you've written your own form serializer, I'm not sure what you need the jQuery Form plugin for. Have you tried passing your JSON object to the jQuery.ajax() function directly?

In first, thanks for the response!

Have you tried passing your JSON object to the jQuery.ajax() function directly?

Yes, I did, works fine, but loses jquery-form's file upload functionallity.

If you've written your own form serializer, I'm not sure what you need the jQuery Form plugin for.

jquery-form has a lot of functionallities that my doesn't has. Also, my serializer only gets some field's values and serializes them into a simple plain object.

I think it would not be a problem if jquery-form serializes my plain object into a serial string, that's what I want (I think so).

I see, I didn't realize you were still using the other features of the plugin. The problem is only in IE9, right? Is it correct in other modern browsers?

At this point, I'm out of ideas. I'm lucky enough not to have to support IE9 anymore, so I'm not sure how well it supports JSON. Perhaps somebody from the community can answer.

It may be easier to get help if you can create a JSFiddle or CodePen example of the error so that others can reproduce the issue you're seeing.

Everything works fine in IE10+. I didn't realize that there's no need of any server side implementation to generate some buggy HTTP headers, so I will create the fiddle ASAP.

Are you still experiencing this issue? If so, would you please create an example of the error on JSFiddle or CodePen so that others can reproduce the issue you're seeing?

I'm going to close this issue until an example can be created.

I probably won't be able to do that because I'm not working in that project anymore and I don't wanna support IE9 anymore, I have no idea why I didn't created that fiddle. xD

Works for me. (and I don't wanna support IE9 anymore either!)

Everything works fine, but I can't send multi-level objects when sending files too; that just happens in IE9, others browsers get the job done without any issues.

I think we can just let this here for maybe someone who gets the same issue in the future.