1. 程式人生 > >IE相容筆記(一):相容IE9表單上傳檔案

IE相容筆記(一):相容IE9表單上傳檔案

幾年前做相容IE8的pc端專案的時候就遇到檔案上傳的需求,當時也是檢視文件來解決IE9以下不支援formData的問題。由於之前沒有寫部落格的習慣,最近又遇到這樣的需求,所以寫出來想幫助需要用到的朋友。

 

本身檔案上傳不難,只需要注意一些細節:

  1. 用最初的表單提交的方式form.submit()
  2. <input type='file'> onchange問題
  3. 點選<input type='file'>問題
  4. 提交表單後跳轉問題

 

一,用最初的表單提交的方式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。