I want to write a file upload script that works in IE but the two types of code that I'm writing have problems in IE.
我想写一个可以在IE中工作的文件上传脚本,但是我写的两种代码在IE中有问题。
Please help. How can you write a file upload script that works in IE?
请帮助。如何编写在IE中工作的文件上传脚本?
Type 1
Problem Not Support File Api In IE (Is the trick not to use it?)
第1类问题不支持IE中的文件Api(不使用它吗?)
selected files: 0; total size: 0
Type 2
Problem Not Support document.getElementById('fileToUpload').files[0](Is the trick not to Get Files[0]?)
类型2问题不支持document.getElementById('fileToUpload')。文件[0](不获取文件的诀窍是[0]吗?)
Please Help :(
请帮助:
51
You can't use these functions unless you're using IE10 or another modern browser. Workarounds are possible for earlier versions of Internet Explorer (and other browsers), but you'll need to adjust your back-end code too.
除非使用IE10或其他现代浏览器,否则无法使用这些功能。对于早期版本的Internet Explorer(和其他浏览器)来说,解决方案是可能的,但是您也需要调整后端代码。
Internet Explorer up until version 10 doesn't support a number of these features, the key ones being the FormData and FileReader APIs. Both of your code snippets rely on the FileReader
API, and the second one also relies on FormData
to upload the file dynamically.
Internet Explorer直到第10版都不支持这些特性,关键的特性是FormData和FileReader api。您的两个代码片段都依赖于FileReader API,第二个代码片段还依赖于FormData来动态上传文件。
I recently wrote a file upload widget that detected these features and served different code depending on support. I used the feature detections from Modernizr, because it's tests are regularly put to the test by the open source community:
我最近编写了一个文件上传小部件,它检测了这些特性,并根据支持提供不同的代码。我使用了来自Modernizr的特性检测,因为它的测试经常被开源社区进行测试:
var support = {
// Are files exposed to JS?
// As used by Modernizr @
// https://github.com/Modernizr/Modernizr/blob/master/feature-detects/file/api.js
'fileReader' : (function testFileReader(){
// Test: look for global file class.
return !!(window.File && window.FileList && window.FileReader);
}()),
// AJAX file upload via formData?
'formData' : window.FormData !== void 0
};
For your fileSelected
function, you'll need support.fileReader
to evaluate true
; for uploadFile
, you need support.formData
.
对于您的文件选择函数,您将需要支持。fileReader评估正确;对于uploadFile,需要support.formData。
Without these features it's impossible to read a file from the front-end or to send a file using AJAX. What you can do, though, is send your file via a hidden 发送文件,并获取UploadHandler。ashx以不同的方式响应非xhr请求。
This solution is technically synchronous (just happening in another, hidden page), so you won't get updates — the only feedback is when the upload is complete and the server has responded. So you will only be able to inform the user as to file name, size, and success once they have completely uploaded it — which might take a while!
这个解决方案在技术上是同步的(只是发生在另一个隐藏的页面中),所以你不会得到更新——唯一的反馈是上传完成后,服务器响应了。所以你只需要告诉用户文件的名称,大小,和成功一旦他们完全上传了它-这可能需要一段时间!
Anyway, the HTML for this would look as follows:
不管怎样,这个HTML看起来是这样的:
selected files:
0
; total size:
0
A few changes:
一些变化:
target
, which means that when it posts its content to the URI in action
, it will load the response in there, as opposed to on the current page.name
reference to an iframe we've included. It is hidden with display:none
, and given a negative tabindex
just to make sure the user doesn't stumble into it. It also has an onload
property specified. This is the only way of binding functions to the load event in older versions of IE.So when the form is submitted, we stay on the current page and the server response loads in our hidden iframe. When that happens, the browser will execute the function named in the onload
attribute. Sadly, this means that function needs to be in the global scope!
因此,当表单提交时,我们停留在当前页面上,服务器响应在隐藏的iframe中加载。当发生这种情况时,浏览器将执行onload属性中命名的函数。遗憾的是,这意味着该函数需要在全局范围内!
I don't know how your back-end works, but if the iframe is to load the response instead of downloading it, it will need to be HTML or plain text (and that will need to be specified in the mime-type). You can tell whether the form was posted via AJAX from the back-end by looking for the X-Requested-With
header, which should have a value of XMLHttpRequest
— if that isn't there, then the iframe is asking for the response and you need to send text or HTML. You may want to stringify a JSON response that exposes the values you wanted to feed back to the user like fileName
, fileSize
& fileType
. I'm hoping you can do this yourself or get a colleague to handle it.
我不知道您的后端是如何工作的,但是如果iframe要加载响应而不是下载它,那么它需要是HTML或纯文本(这需要在mime类型中指定)。您可以通过查找X-Requested-With报头(它应该有XMLHttpRequest的值)来从后端判断表单是通过AJAX发布的,如果没有,那么iframe请求响应,您需要发送文本或HTML。您可能希望对JSON响应进行字符串化,该响应公开您想要反馈给用户的值,如文件名、fileSize和fileType。我希望你能自己做这件事,或者找个同事来处理。
As mentioned, the response handler function will need to be in the global scope for the onload
attribute to bind to, because of old IE being very quirky. I see you're using jQuery, so if you went down the route of stringifying the server response, you could write this function as follows:
如前所述,响应处理程序函数需要在onload属性的全局范围内绑定,因为老IE非常古怪。我看到您正在使用jQuery,所以如果您沿着字符串化服务器响应的路线,您可以编写如下函数:
function parseIframeResponse(){
var respOnse= $('#fileIframe').contents().find('body').text();
var object = $.parseJSON(response);
}
Issues with the iframe
load
event bindingiframe负载事件绑定问题
As mentioned earlier, the iframe load event needs to be bound inline as an attribute of the iframe itself — this is because IE will simply fail to register it otherwise. But this is problematic in and of itself because even an empty iframe (an empty or non-present
src
will default toabout:blank
) fires a load event. To mitigate this you will need to discard anyresponse
that evaluates to an empty string as a false positive, and make sure your back-end responds with some content even if it encounters a fault.如前所述,iframe load事件需要作为iframe本身的一个属性内联地绑定—这是因为IE将无法注册它。但这本身就有问题,因为即使是空的iframe(一个空的或不存在的src也会默认为:blank)触发一个加载事件。为了减轻这一点,您将需要丢弃任何对空字符串计算为假阳性的响应,并确保您的后端对某些内容进行响应,即使它遇到了错误。
Presumably, you would then want to use whatever information is in there to execute some of the code you've currently got in the functions fileSelected
, uploadProgress
, etc.
然后,您可能会想要使用那里的任何信息来执行您当前在函数文件、uploadProgress等功能中获得的一些代码。
Hope this helps.
希望这个有帮助。
In hindsight, despite writing this off the back of having developed my own solution to the problem, it could be considered negligent not to mention Fine Uploader, a heavily tested (over 700 closed issues!) and well maintained stand-alone plugin that aims to achieve the best file upload experience possible for IE7 and up. There's also a good selection of back-end server components — including ASP.NET — to parse the upload. You might find it easier to tweak this than roll your own!
事后看来,尽管写这后面的开发自己的解决方案,它可以被认为是过失更不用说好上传,大量测试(在700年关闭问题!),保持独立的插件,旨在实现最佳文件上传可能IE7和经验。还有很好的后端服务器组件选择——包括ASP。NET -解析上传。你可能会发现调整这个比自己动手更容易!
load
event. Amended answer in place.