怎么了?
互联网上有很多关于制作ajax jquery表单来上传图像的例子。这样地:

<form id="imageform" method="post" enctype="multipart/form-data" action='ajaximage.php'>
<input type="file" name="photoimg" id="photoimg" />
</form>

让这个表格上传一个文件并不难,但我需要其他东西。
我有一个比那大一点的表格。
例子:
<form id="imageform" method="post" enctype="multipart/form-data" action='ajaximage.php'>
<input type="file" name="photoimg" id="photoimg" />
<input type="text" name="foo"/>
<input type="text" name="bar"/>
<input type="submit" value="FINALLY DO THE SUBMIT"/>
</form>

有什么大不了的?
好吧,我希望文件输入字段完成文件onchange事件的上载。但我不想让洞表来提交。还有其他字段需要完成,毕竟用户将完成最终提交。
我没有问题在后端这样做,我的PHP引擎正在等待和工作,但我不知道如何在前端这样做。
有什么建议吗?

最佳答案

您可以使用target元素的<form>属性提交表单,而无需重新加载页面。额外的字段仍将被发送,但是通过动态交换<form>属性,例如actionenctype,您可以确保文件输入将被发送到后端的某个点。
我已经编写了一个简单的JavaScript+jQuery组件,它允许您快速设置AJAX上传程序。它将自动处理属性更改,并允许后端在前端触发回调:

var uploader = {

    functionBegin: function () {},
    functionCallback: function () {},

    formID: '',
    formAction: '',

    buttonID: '',

    originalAction: '',
    originalTarget: '',
    originalEnctype: '',
    originalOnSubmit: '',

    isSetup: false,

    // Initializes the AJAX uploader
    init: function(formID, buttonID, formAction, beginFunction, callbackFunction) {

        // Sets up the optional callback functions
        this.functionBegin = beginFunction;
        this.functionCallback = callbackFunction;

        // Sets up the selectors and upload form atributes
        this.formID = formID;
        this.buttonID = buttonID;
        this.formAction = formAction;

        // If we haven't already, create the invisible IFRAME that our form will target
        if(!this.isSetup) {
            $(formID).append('<iframe id="AU_IFrame" name="AU_IFrame" src="about:blank" style="width:0;height:0;border:0px solid #fff;"></iframe>');
            this.isSetup = true;
        }

        // If a button selector was defined, we hook it's click event
        if(buttonID) {
            $(buttonID).click(function () {
                uploader.triggerBegin();
                return false;
            });
        }

    },

    // Begins the file upload
    triggerBegin: function() {

        // Backs up the original form attributes
        this.originalAction = $(this.formID).attr('action');
        this.originalTarget = $(this.formID).attr('target');
        this.originalEnctype = $(this.formID).attr('enctype');
        this.originalOnSubmit = $(this.formID).attr('onSubmit');

        // Sets up the form with our upload attributes
        $(this.formID).attr('action', this.formAction);
        $(this.formID).attr('target', 'AU_IFrame');
        $(this.formID).attr('enctype', 'multipart/form-data');

        // Call our 'on upload begin' callback, if defined
        if(this.functionBegin) {
            this.functionBegin();
        }

        // Submit the upload form
        $(this.formID).submit();

        // Now that it's already uploaded, revert back to the original attributes
        $(this.formID).attr('action', this.originalAction);
        $(this.formID).attr('target', this.originalTarget);
        $(this.formID).attr('enctype', this.originalEnctype);
        $(this.formID).attr('onSubmit', this.originalOnSubmit);

    },

    // This can be called from the back-end, will trigger the user-defined callback
    triggerCallback: function(params) {
        if(this.functionCallback) {
            this.functionCallback(params);
        }
    }


};

下面是一个如何在HTML表单中应用此功能的示例:
<form name="test" method="POST" action="regularForm.php">
    <input id="fileInput" name="fileInput" type="file" />
    <input type="text" name="foo" />
    <input type="text" name="bar" />
    <input type="submit" value="Send" />
</form>

<script type="text/javascript">
    $(function () {

        uploader.init(
            '#fileInput', // File field selector
            null, // Upload button selector (Optional, since we'll upload on change, this won't be needed here)
            'fileUpload.php', // Upload action
            function () { // Callback on upload begin (optional)
                alert("Starting upload!");
            },
            function (params) { // Callback on upload end/error (called by the back-end, optional)
                alert("Upload successful");
            }
        );

        $('#fileInput').change( upload.triggerBegin ); // automatically upload on file input change

    });
</script>

要正确触发回调,只需确保后端将运行以下命令(假设您使用的是PHP):
$someParameter = "whatever you want to return in the callback";

echo '<script type="text/javascript">';
echo 'if(top.uploader && top.uploader.triggerCallback) { top.uploader.triggerCallback("'.$someParameter.'"); }';
echo '</script>';

您可以自然地调整参数使其返回,例如,文件URL、上传状态、大小等。
至于其他解决方案,如果没有HTML5,唯一的选择就是使用Flash/Silverlight/Java applet或Google Gears插件来处理文件的挑选和上传。有很多jQuery插件实现了所有的备选方案,作为逐步的回退:
jqUploader
Uploadify
SWFUpload
In-a-Flash Uploader

09-04 22:57
查看更多