Загрузка файла iframe в jQuery
Я строю загрузку файла с помощью 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>
5 ответов
Я нашел решение. Этот код работает:
<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>
Это не официальный плагин, но вот пример того, как вы можете обернуть логику отправки формы в плагин.
Пример:
<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);
Это хороший плагин для загрузки файлов с помощью ajax
Ваша цель формы должна совпадать с именем 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>
И после этого вы можете прикрепить событие к кнопке ввода, чтобы прослушать "изменение". Более того, вы можете получить прогресс от сервера, используя jsonp, и все это будет работать в любом событии браузера IE3+. Что-то вроде этого:
$('input').change(function () {
$('form').submit();
});
$.getJSON('/echo/jsonp/?callback=?', function(e, progress) {
console.log(progress);
});
Вы знаете, вместо того, чтобы загружать один и тот же элемент несколько раз, почему бы просто не использовать его повторно:
var form = $('#theuploadform');
form.attr("action", "/ajax/user.asmx/Upload");
form.attr("method", "post");
// and so on
Что за ошибка у вас? Вы можете опубликовать это?
ОБНОВИТЬ
Поскольку вы не можете установить атрибут самостоятельно, вот обходной путь:
Поместите форму в iframe и прикрепите событие onchange к кнопке ввода. когда пользователь выбирает файл, вы запускаете необходимый код для загрузки файла (отправки), тогда родительское окно может закрыть iframe.