Javascript jQuery iframe 文件上传
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7909161/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery iframe file upload
提问by
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>
回答by
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>
回答by plalx
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);
回答by Ajouve
This is a good plugin to upload files using ajax
这是一个使用ajax上传文件的好插件
回答by AuthorProxy
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+. Something like this:
在此之后,您可以将事件附加到输入按钮以侦听“更改”。此外,您可以使用 jsonp 从服务器获取进度,所有这些都适用于任何浏览器事件 IE3+。像这样的东西:
$('input').change(function () {
$('form').submit();
});
$.getJSON('/echo/jsonp/?callback=?', function(e, progress) {
console.log(progress);
});
回答by Ibu
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
更新
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. 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 中,并将 onchange 事件附加到输入按钮。当用户选择一个文件时,您触发必要的代码上传文件(提交),然后父窗口可以关闭 iframe。