幾年前做相容IE8的pc端項目的時候就遇到檔案上傳的需求,當時也是檢視文檔來解決IE9以下不支援formData的問題。由于之前沒有寫部落格的習慣,最近又遇到這樣的需求,是以寫出來想幫助需要用到的朋友。
本身檔案上傳不難,隻需要注意一些細節:
- 用最初的表單送出的方式form.submit()
- <input type='file'> onchange問題
- 點選<input type='file'>問題
- 送出表單後跳轉問題
一,用最初的表單送出的方式form.submit()
在IE9中不支援formData對象,無法使用ajax上傳檔案,是以通過在一個form表單中直接送出到伺服器上傳。
<form>
<input type="file">
</form>
<button onclick="submit()">上傳</button>
<script>
function submit() {
var form = document.forms[0]
form.submit()
}
</script>
注意:如果要擷取file的内容,主流浏覽器可以通過擷取input對象e.files[0]拿到,在IE9以下由于安全政策的因素不支援直接擷取,但是可以通過微軟在IE浏覽器下支援的ActiveXObject對本地檔案進行操作(有關ActiveXObject對象的了解可以點選這裡),例如可以像下面這樣拿到檔案大小:
<script>
var path = '' // 這裡是你的檔案路徑
var fso = new ActiveXObject('Scripting.FileSystemObject')
var fileSize = fso.GetFile(path).size
console.log('檔案大小是:', fileSize)
</script>
二,<input type='file'> onchange問題
有時候需要在選擇完檔案立馬上傳,這是可以在标簽<input type='file'>上添加onchange事件來進行送出表單,但是如果之前選擇了一個檔案沒有清空,那麼onchange事件不會觸發,是以這裡需要在适當的地方對檔案清空。例如:
<form>
<input type="file" onchange="submit()">
</form>
<script>
function submit() {
var form = document.forms[0]
form.submit()
form.reset() // 送出完進行重置form表單
}
</script>
三,點選<input type='file'>問題
這裡有幾個點注意:
- IE 9中隻能送出使用者通過标簽點選選擇的檔案
- IE9,IE10和火狐無法點選button标簽中的<input type='file'>
- 修改浏覽器預設<input type='file'>的樣式
IE9出于安全性考慮無法送出除使用者通過标簽點選選擇的檔案,但是其他主流浏覽器可以這樣選擇并上傳檔案:
<form>
<input id="fileId" type="file">
</form>
<button onclick="select()">選擇檔案</button>
<script>
function select() {
var inputFile = document.getElementById('fileId')
inputFile.click()
}
</script>
上面這種方式在IE9中可以選擇檔案,但是送出表單不會成功。是以隻能點選<input type='file'>标簽來上傳,由于浏覽器預設的标簽樣式很醜,這裡可以采取下面這樣來修改達到美化的效果:
<style>
form>span {
display: inline-block;
border: 1px solid #aaa;
padding: 5px 15px;
overflow: hidden;
position: relative;
}
#fileId {
opacity: 0;
position: absolute;
top: 0;
right: 0; // 注意:這裡不用left:0;的原因是IE的點選區域在右邊,左邊是輸入區域
bottom: 0;
font-size: 30px; // 這裡是為了把<input type='file'>的點選按鈕撐大以完全覆寫父元素
}
</style>
<form>
<span>
<input id="fileId" type="file">
上傳
</span>
<button>
<input id="fileId" type="file"> // 放在button裡面在IE9,IE10和火狐有問題
上傳
</button>
</form>
上面代碼主要是通過把<input type='file'>标簽放在一個span标簽裡面,然後隐藏input标簽并給span添加樣式(注意:<input type='file'>放在button标簽裡面在IE9,IE10和火狐中會有問題,外面用span标簽包裹就好了),這裡隐藏的<input type='file'>需要全部覆寫span标簽,不然點選span的某些區域無法觸發input的選擇檔案事件,下面是美化前後的對比:
美化前IE中:

美化前谷歌中:
美化後:
可以看到美化後和一般的按鈕沒什麼差別了。
四,送出表單後跳轉問題
正常送出表單後會跳轉頁面,有時候不希望跳轉,則需要用一個隐藏的iframe來接受表單送出的結果。例如:
<form action='http://' method='post' target='targetIframe'>
<input type="file" onchange="submit()">
</form>
<iframe name='targetIframe' style="display: none;">
</iframe>
<script>
function submit() {
var form = document.forms[0]
form.submit()
form.reset() // 送出完進行重置form表單
}
</script>
上面主要是需要指定form的target屬性與iframe的name一緻,這樣送出表單後不會重新整理頁面,并且在iframe的body中可以拿到傳回的資料。
注意: 在IE9中如果傳回的是json格式的資料不會被解析,這時會彈出提示框是否要下載下傳。解決方法是背景修改response的content-type為text/plain或text/html。