使用“表单插件”上传 Ajax 文件对于 jQuery

发布于 2024-11-06 18:55:59 字数 2440 浏览 0 评论 0原文

我正在使用 jQuery,我想使用 Ajax 上传文件。我进行了一些搜索,发现这是不可能的。

然而,有一个 jQuery 插件,jQuery Form Plugin,它允许我们上传文件通过阿贾克斯。

它工作得很好,但我有一个特殊的问题。这是我的代码:

$('#question-form').submit(function() {
    var serialAnswers = '';

    // Create a query string given some fields
    // Format of the query string : answers[0][fr_fr][0]=a1fr&answers[0][fr_fr][1]=2&answers[0][en_uk][0]=a1en&answers[0][en_uk][1]=6&...
    $('#question-answers > div').each(function(idx, elt) {
        $('div[lang]', $(elt)).each(function(idxLang, eltLang) {
            var lang = $(this).attr('lang');
            serialAnswers += 'answers[' + idx + '][' + lang + '][0]=' + $("[answerpart=display]", $(eltLang)).val();
            serialAnswers += '&answers[' + idx + '][' + lang + '][1]=' + $("[answerpart=value]", $(eltLang)).val() + '&';
        });
    });

    $(this).ajaxSubmit({
        datatype: "html",
        type: "POST",
        data: serialAnswers,
        url: $(this).attr("action"),
        success: function(retour) {
            $('#res-ajax').html(retour);
        }
    });

    return false;
});

如您所见,我必须将 $.ajax 调用替换为 $(this).ajaxSubmit() 调用,并具有相同的选项。此外,我必须根据某些字段创建一个查询字符串(代码中的serialAnswers),以便将其传输到PHP代码。

这是我在没有文件可上传时所做的事情。我刚刚序列化了表单字段并添加了名为serialAnswers的查询字符串:

$.ajax({
    datatype: "html",
    type: "POST",
    data: $(this).serialize() + '&' + serialAnswers,
    url: $(this).attr("action")
    success: function(retour) {
        $("#res-ajax").html(retour);
    }
});

但我的问题是表单插件以这种方式(在PHP文件中)传输我的附加数据(查询字符串):

Array
(
    [question_heading_fr_fr] => something
    [question_heading_en_uk] => nothing
    [question_type] => 5
    [0] => a
    [1] => n
    [2] => s
    [3] => w
    [4] => e
    [5] => r
    [6] => s
    [7] => [
    [8] => 0
    [9] => ]
    [10] => [
    [11] => f
    [12] => r
    [13] => _
    [14] => f
    [15] => r
    [16] => ]
    ....
)

根据文档,我必须传递一个JSON 对象到数据选项,如下所示:

data: { key1: 'value1', key2: 'value2' }

但我不知道如何将查询字符串转换为 JSON 对象,以及它是否会在 PHP 端解释为数组。

有解决办法吗?

编辑:即使我使用 iframe,我也不知道如何添加包含非来自表单的信息的查询字符串(我的 serialAnswer 来自上面的代码)。

I am using jQuery, and I would like to upload files with Ajax. I have made some searches and found it is not possible.

However, there is one jQuery plugin, jQuery Form Plugin, which allows us to upload files through Ajax.

It works very well, but I have a special problem. Here is my code:

$('#question-form').submit(function() {
    var serialAnswers = '';

    // Create a query string given some fields
    // Format of the query string : answers[0][fr_fr][0]=a1fr&answers[0][fr_fr][1]=2&answers[0][en_uk][0]=a1en&answers[0][en_uk][1]=6&...
    $('#question-answers > div').each(function(idx, elt) {
        $('div[lang]', $(elt)).each(function(idxLang, eltLang) {
            var lang = $(this).attr('lang');
            serialAnswers += 'answers[' + idx + '][' + lang + '][0]=' + $("[answerpart=display]", $(eltLang)).val();
            serialAnswers += '&answers[' + idx + '][' + lang + '][1]=' + $("[answerpart=value]", $(eltLang)).val() + '&';
        });
    });

    $(this).ajaxSubmit({
        datatype: "html",
        type: "POST",
        data: serialAnswers,
        url: $(this).attr("action"),
        success: function(retour) {
            $('#res-ajax').html(retour);
        }
    });

    return false;
});

As you can see, I have to replace the $.ajax call by a $(this).ajaxSubmit() call, with the same options. Moreover, I have to create a query string (serialAnswers in the code) according to some fields in order to transmit it to the PHP code.

Here is what I used to do when I had no file to upload. I just serialized the form fields and added my query string named serialAnswers:

$.ajax({
    datatype: "html",
    type: "POST",
    data: $(this).serialize() + '&' + serialAnswers,
    url: $(this).attr("action")
    success: function(retour) {
        $("#res-ajax").html(retour);
    }
});

But my problem is that the form plugin transmits my additional data (the query string) that way (in the PHP file):

Array
(
    [question_heading_fr_fr] => something
    [question_heading_en_uk] => nothing
    [question_type] => 5
    [0] => a
    [1] => n
    [2] => s
    [3] => w
    [4] => e
    [5] => r
    [6] => s
    [7] => [
    [8] => 0
    [9] => ]
    [10] => [
    [11] => f
    [12] => r
    [13] => _
    [14] => f
    [15] => r
    [16] => ]
    ....
)

According to the documentation, I have to pass a JSON object to the data option, like this:

data: { key1: 'value1', key2: 'value2' }

But I don't know how to convert my query string to a JSON object and if it would be interpreted as an array on the PHP side.

Is there a solution?

EDIT: Even if I use an iframe, I don't know how to add a query string with information which does not come from the form (my serialAnswer from the code above).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

终遇你 2024-11-13 18:55:59

尝试Uploadify。这是一个基于 Flash 的上传插件。实现简单,支持多文件上传。

Try Uploadify. This is a Flash based upload plugin. It is easy to implement and supports multiple file upload.

蝶舞 2024-11-13 18:55:59

我不确定你到底在寻找什么,但为什么你不能这样做:

data: {'key1':$(this).serialize(),'key2': serialAnswers}

然后在 PHP 端解码 PHP 你做的

json_decode($arr); //Where $arr is whatever the array is that gets passed

如果你需要传回 JSON 响应,你只需做:

json_encode($arr); //Where arr is an array you build within your script

我假设这就是你做的想。

I'm not sure exactly what your looking for but why can't you just do:

data: {'key1':$(this).serialize(),'key2': serialAnswers}

Then on the PHP side to decode PHP you do

json_decode($arr); //Where $arr is whatever the array is that gets passed

If you need to pass back a JSON response you just do:

json_encode($arr); //Where arr is an array you build within your script

I'm assuming this is what you want.

暮年慕年 2024-11-13 18:55:59

编辑:我找到了一个新的解决方案,并且它有效:)

我已经修改了 jQuery 表单插件。插件页面:http://jquery.malsup.com/form/#getting-started。脚本: https://github.com/malsup/form/raw/master /jquery.form.js

为了使用此语法:

$('#myform').submit(function() {
    var queryString = 'answers[0][fr_fr][0]=a1fr&answers[0][fr_fr][1]=2&answers[0][en_uk][0]=a1en&answers[0][en_uk][1]=6';

    $(this).ajaxSubmit({
        dataType:  'html',
        data: queryString
    });

    return false; 
});

而不是:

$('#myform').submit(function() {
    $(this).ajaxSubmit({
        dataType:  'html',
        data: {'key':'value' }
    });

    return false; 
});

我修改了插件代码。

找到这个:

var n,v,a = this.formToArray(options.semantic);
if (options.data) {
    options.extraData = options.data;
    for (n in options.data) {
        if(options.data[n] instanceof Array) {
            for (var k in options.data[n]) {
                a.push( { name: n, value: options.data[n][k] } );
            }
        }
        else {
            v = options.data[n];
            v = $.isFunction(v) ? v() : v; // if value is fn, invoke it
            a.push( { name: n, value: v } );
        }
    }
}

并删除所有if (options.data)及其内容。在这些代码之后的几行中,找到以下内容:

var q = $.param(a);

并在其后面添加以下内容:

if (options.data) {
    options.extraData = options.data;
    q += '&' + options.data;
}

在函数 fileUpload() 中,找到以下内容:

var extraInputs = [];
try {
    if (s.extraData) {
        for (var n in s.extraData) {
            extraInputs.push(
                $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />')
                    .appendTo(form)[0]);
        }
    }

    // Add iframe to doc and submit the form
    $io.appendTo('body');
    io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
    form.submit();
}

并将其替换为:

var extraInputs = [];
try {
    if (s.extraData) {
        var couples = s.extraData.split('&');
        for (var c=0 ; c < couples.length ; c++)
        {
            var couple = couples[c].split('=');
            extraInputs.push(
                $('<input type="hidden" name="'+couple[0]+'" value="'+couple[1]+'" />')
                    .appendTo(form)[0]);
        }
    }

    // add iframe to doc and submit the form
    $io.appendTo('body');
    io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
    form.submit();
}

由于这些修改,您现在可以添加查询字符串并同时上传图像时间。

EDIT: I found a new solution, and it works :)

I have modified the jQuery Form Plugin. Plugin page: http://jquery.malsup.com/form/#getting-started. Script: https://github.com/malsup/form/raw/master/jquery.form.js

In order to use this syntax:

$('#myform').submit(function() {
    var queryString = 'answers[0][fr_fr][0]=a1fr&answers[0][fr_fr][1]=2&answers[0][en_uk][0]=a1en&answers[0][en_uk][1]=6';

    $(this).ajaxSubmit({
        dataType:  'html',
        data: queryString
    });

    return false; 
});

instead of:

$('#myform').submit(function() {
    $(this).ajaxSubmit({
        dataType:  'html',
        data: {'key':'value' }
    });

    return false; 
});

I have modified the plugin code.

Find this:

var n,v,a = this.formToArray(options.semantic);
if (options.data) {
    options.extraData = options.data;
    for (n in options.data) {
        if(options.data[n] instanceof Array) {
            for (var k in options.data[n]) {
                a.push( { name: n, value: options.data[n][k] } );
            }
        }
        else {
            v = options.data[n];
            v = $.isFunction(v) ? v() : v; // if value is fn, invoke it
            a.push( { name: n, value: v } );
        }
    }
}

And delete all the if (options.data) and its content. A few lines after these ones, find this:

var q = $.param(a);

And add this right after it:

if (options.data) {
    options.extraData = options.data;
    q += '&' + options.data;
}

In the function fileUpload(), find this:

var extraInputs = [];
try {
    if (s.extraData) {
        for (var n in s.extraData) {
            extraInputs.push(
                $('<input type="hidden" name="'+n+'" value="'+s.extraData[n]+'" />')
                    .appendTo(form)[0]);
        }
    }

    // Add iframe to doc and submit the form
    $io.appendTo('body');
    io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
    form.submit();
}

And replace it by:

var extraInputs = [];
try {
    if (s.extraData) {
        var couples = s.extraData.split('&');
        for (var c=0 ; c < couples.length ; c++)
        {
            var couple = couples[c].split('=');
            extraInputs.push(
                $('<input type="hidden" name="'+couple[0]+'" value="'+couple[1]+'" />')
                    .appendTo(form)[0]);
        }
    }

    // add iframe to doc and submit the form
    $io.appendTo('body');
    io.attachEvent ? io.attachEvent('onload', cb) : io.addEventListener('load', cb, false);
    form.submit();
}

You now can add a query string thanks to these modifications and uploading an image at the same time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文