简体   繁体   English

jQuery iframe文件上传

[英]jQuery iframe file upload

Im building a file upload with jQuery, but Im getting a jQuery error trying to set the attributes of the form: 我用jQuery构建文件上传,但是我在尝试设置表单属性时遇到了jQuery错误:

$(document).ready(function () {
    $("#formsubmit").click(function () {

        var iframe = $('<iframe name="postframe" id="postframe" class="hidden" src="about:none" />');

        $('div#iframe').append(iframe);

        $('#theuploadform').attr("action", "/ajax/user.asmx/Upload")
        $('#theuploadform').attr("method", "post")
        $('#theuploadform').attr("userfile", $('#userfile').val())
        $('#theuploadform').attr("enctype", "multipart/form-data")
        $('#theuploadform').attr("encoding", "multipart/form-data")
        $('#theuploadform').attr("target", "postframe")
        $('#theuploadform').submit();
        //need to get contents of the iframe

        $("#postframe").load(
            function () {
                iframeContents = $("iframe")[0].contentDocument.body.innerHTML;
                $("div#textarea").html(iframeContents);
            }
        );
    }
);


<div id="uploadform">
    <form id="theuploadform" action="">
        <input id="userfile" name="userfile" size="50" type="file" />
        <input id="formsubmit" type="submit" value="Send File" />
    </form>
</div>

<div id="iframe" style="width: 0px; height: 0px; display: none;">
</div>

<div id="textarea">
</div>

I found the solution. 我找到了解决方案。 This code works: 此代码有效:

<script type="text/javascript">

    $(document).ready(function () {

        $("#formsubmit").click(function () {

            var iframe = $('<iframe name="postiframe" id="postiframe" style="display: none"></iframe>');

            $("body").append(iframe);

            var form = $('#theuploadform');
            form.attr("action", "/upload.aspx");
            form.attr("method", "post");

            form.attr("encoding", "multipart/form-data");
            form.attr("enctype", "multipart/form-data");

            form.attr("target", "postiframe");
            form.attr("file", $('#userfile').val());
            form.submit();

            $("#postiframe").load(function () {
                iframeContents = this.contentWindow.document.body.innerHTML;
                $("#textarea").html(iframeContents);
            });

            return false;

        });

    });

</script>


<form id="theuploadform">
    <input id="userfile" name="userfile" size="50" type="file" />
    <input id="formsubmit" type="submit" value="Send File" />
</form>

<div id="textarea">
</div>

It's not an official plugin, however here's an example on how you could wrap the form's submitting logic into a plugin. 它不是官方插件,但是这里有一个关于如何将表单的提交逻辑包装到插件中的示例。

Example: 例:

<form method="post" enctype="multipart/form-data">
    <input name="file" type="file" />

    <input type="text" name="test" />

    <button type="submit">Submit</button>
</form>

<script>
    $('form').submit(function (e) {

        //prevent default submit
        e.preventDefault();

        //submit through frame
        $(this).frameSubmit({
            done: function (form, frame, options) {
                console.log('done!');
            },
            fail: function (form, frame, options) {
                console.log('fail!');
            },
            always: function (form, frame, options) {
                console.log('always!');
            }

            //custom hasError implementation if needed
            //by default if the frame's body HTML contains the text "unexpected error" or "server error"
            //it is treated as an error
            /*,hasError: function (frame) {
                return false;
            }*/
        });
    });

</script>

PLUGIN 插入

!function ($, doc) {
    var _frameCount = 0,
        _callbackOptions = ['done', 'fail', 'always'],
        _hasFailed = function (frame) {
            var frameHtml = $(frame).contents().find('body').html();

            return /(server|unexpected)\s+error/i.test(frameHtml);
        },
        _createFrame = function () {
            return $('<iframe>').prop('name', 'jq-frame-submit-' + _frameCount++).hide().appendTo(doc.body);
        };

    $.fn.extend({
        frameSubmit: function (options) {

            return this.each(function () {
                var deferred = $.Deferred(),
                    form = this,
                    initialTarget = form.target,
                    hasTarget = form.hasAttribute('target'),
                    hasFailed = options.hasFailed || _hasFailed,

                    //The initial frame load will fire a load event so we need to
                    //wait until it fires and then submit the form in order to monitor
                    //the form's submission state.
                    $frame = _createFrame().one('load', function () {
                        $frame.one('load', function () {
                            deferred[hasFailed(this) ? 'reject' : 'resolve'](form, this, options);
                            $frame.remove();
                        });

                        form.submit();

                        //restore initial target attribute's value
                        if (hasTarget) form.target = initialTarget;
                        else form.removeAttribute('target');
                    });

                //attach handlers to the deferred
                $.each(_callbackOptions, function (i, optName) {
                    options[optName] && deferred[optName](options[optName]);
                });

                //make sure the form gets posted the to iframe
                form.target = $frame.prop('name');
            });
        }
    });
}(jQuery, document);

Your form target should be the same as iframe name, for example: 您的表单目标应与iframe名称相同,例如:

<form target="frame" 
      action="http://posttestserver.com/post.php?dir=example" 
      method="post"
      enctype="multipart/form-data">
    <input name="file" type="file"/>
</form>

<iframe name="frame"></iframe>

And after this you can attach event to input button to listen for 'change'. 在此之后,您可以将事件附加到输入按钮以收听“更改”。 Furthemore you can get progress from server using jsonp and all of this will work in any browser event IE3+. 此外,您可以使用jsonp从服务器获得进展,所有这些都适用于任何浏览器事件IE3 +。 Something like this: 像这样的东西:

$('input').change(function () {
    $('form').submit();
});

$.getJSON('/echo/jsonp/?callback=?', function(e, progress) {
    console.log(progress);
});

This is a good plugin to upload files using ajax 这是一个使用ajax上传文件的好插件

http://jquery.malsup.com/form/#file-upload http://jquery.malsup.com/form/#file-upload

You know instead of fetching the same item multiple times, why not just reuse it: 您知道不是多次获取同一个项目,为什么不重复使用它:

var form = $('#theuploadform');
form.attr("action", "/ajax/user.asmx/Upload");
form.attr("method", "post");
// and so on

What kind of error are you having? 你有什么样的错误? can you post it? 你可以发布吗?

UPDATE UPDATE

Since you cannot set the attribute yourself here is a work around: 既然你不能自己设置属性,这是一个解决方法:

Put the form in an iframe, and attach an onchange event to the input button. 将表单放在iframe中,并将onchange事件附加到输入按钮。 when the user select a file, you trigger the necessary code to upload the file (submit), then the parent window can close the iframe. 当用户选择文件时,触发上传文件所需的代码(提交),然后父窗口可以关闭iframe。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM