不得不说这个问题困扰了我很久,百度、google了一大把,想起了那句话:“有问题找百度,百度不行就谷歌,谷歌再找不到就自杀。”
?
中文搜索了一大通还是找不到答案,改成英文的,很快找到问题所在,看来以后要多变换一下思维,不要在惯性思维的树上吊死了。
?
原文如下:
Anyway, people found a relatively popular way to do this. The ideia is having a hidden iframe on the page, and use that iframe as a target of the form where you have the reference to the file to upload. So, when the form submits, the result page will go to the hidden iframe, and the user won’t see a full page refresh. You still have to take care of some details, like hiding the form and showing a nice progress bar with the classic “Hold on, we are uploading” message, and polling for the content of the iframe to check is the file is still in its way, or if it arrived safely.
One nice detail is where do you actually have the hidden iframe. You could just put the iframe on the HTML code of your page, but IMO that’s ugly. The iframe is an artifact that is needed just to serve as a black hole for the form submittion result page. It doesn’t make sense to put it in your HTML code, as it hasn’t anything to do with the content. Also, it’s error prone: you may inadvertently delete it, causing the file upload to missbehave. Or you may need to change the iframe code and having it on HTML will force you to update on all the pages where you use it (and of course, you will forget one).
So, I believe the most elegant solution (if you can use the word “elegance” in the context of this major hack) is to generate the iframe using javascript. You may do this on the page load, when you create the form, whatever. Just do it before the user submits the file! :) Well, it’s easy, right? Something like this does the trick:
var objBody = document.getElementsByTagName("body").item(0);
var iframe = document.createElement('iframe');
iframe.id = 'fileUploaderEmptyHole';
iframe.name = 'fileUploaderEmptyHole';
iframe.width = 0;
iframe.height = 0;
iframe.marginHeight = 0;
iframe.marginWidth = 0;
objBody.insertBefore(iframe, objBody.firstChild);
That’s cool, right? Just run this and the iframe will be created. Submit the form, the result goes in the hidden iframe, everything works, we are done, let’s go home. Well… all true until you actually test it on Internet Explorer…
If you test this on IE, the result will be a new window being created when you submit, which is clearly not what you want. Well, I had a hard time finding the problem, so here goes: if you create the iframe using JavaScript, IE wont set it’s name. Yes, the “iframe.name = ‘fileUploaderEmptyHole’;” line will simply be ignored. It does nothing. So, as you don’t have any frame called ‘fileUploaderEmptyHole’, when you submit the form, it will create a new window named ‘fileUploaderEmptyHole’ and display the result on it.
The solution it to hack this even further. Specifically:
iframe = document.createElement('<iframe name="fileUploaderEmptyHole">');
Yeah! Now you’re thinking “WTF?”. Yes, yes, it’s true. This actually works on IE, with the expected (?) results. Well, you still have to support the other browsers, but you are lucky, as this will throw an exception on all the non-IE browsers. So, it’s just a matter of catching it, and running the decent version of the code:
var iframe;
try {
iframe = document.createElement('<iframe name="fileUploaderEmptyHole">');
} catch (ex) {
iframe = document.createElement('iframe');
}
iframe.id = 'fileUploaderEmptyHole';
iframe.name = 'fileUploaderEmptyHole';
iframe.width = 0;
iframe.height = 0;
iframe.marginHeight = 0;
iframe.marginWidth = 0;
This is why I love the Web. Or maybe not.
?
?
关键是这句话:
If you test this on IE, the result will be a new window being created when you submit, which is clearly not what you want. Well, I had a hard time finding the problem, so here goes: if you create the iframe using JavaScript, IE wont set it’s name. Yes, the “iframe.name = ‘fileUploaderEmptyHole’;” line will simply be ignored. It does nothing. So, as you don’t have any frame called ‘fileUploaderEmptyHole’, when you submit the form, it will create a new window named ‘fileUploaderEmptyHole’ and display the result on it.
?
问题所在:在IE下,通过JS创建一个iframe object,对其name属性的赋值操作将被忽略。
解决方式:在IE和其他browser下可以通过以下方式创建iframe
?
var iframe;
try { // for I.E.
iframe = document.createElement('<iframe name="fileUploaderEmptyHole">');
} catch (ex) { //for other browsers, an?exception will be?thrown
iframe = document.createElement('iframe');
}
英文很容易读,剩下的就自己动手解决吧。