兼容ie9圖片上傳,解決ie9下提示下載或保存

如果不考慮ie9兼容性,實現【上傳圖片】大致的思路如下:

  1. 由于公司是將所有上傳的圖片都放到【代理服務器】里。所以【上傳圖片】其實是上傳到【代理服務器】。可以通過ajax,通過FormData將圖片上傳到【代理服務器】。
  2. 從【代理服務器】拿到的回調里,有壓縮過的圖片的url,將這個url賦值給DOM里圖片img的src就行了。由于我們的項目是用的vue,直接綁定:src就行了。
  3. 上傳圖片到【代理服務器】完成后,需要將url等相關數據(我們的項目后端需要一個pid,來實現用戶下次訪問時,后端從代理服務器根據這個pid來獲取相應圖片】),通過ajax發給后端(我們公司的服務器)。

思路很簡單,而且核心關鍵其實就是第1點,第2,3只是簡單的DOM操作和ajax交換數據。接下來就只關注第1點的具體實現。

1. 通過formData,結合html5的input type=file來實現上傳

<input name="file" type="file" @change="update" accept="image/x-png, image/jpg, image/jpeg">

對應的,Vue的methods里,update方法如下:

update(e) {

  let file = e.target.files[0]; //input提供的API,如果需要過濾圖片尺寸,也可以在e.target.files[0]里拿到相應數據。

  let param = new FormData(); //通過FormData來將圖片信息發送給服務器;FormData是html5的私有對象。

  param.append('file', file, file.name);

/* 接下來,就是通過ajax,發送form數據到服務器,我們公司用的jQuery,比較普遍的應該是axios吧 */

  $.ajax({

    url: '/image/upload',

    type: 'POST',

    data: param, //保證data格式為FormData

    processData: false, //必須false才會自動加上正確的Content-Type

    contentType: false //必須false才會避開jQuery對 formdata 的默認處理

  }).done(function(res) {

  // 回調

  })

}

然后,在回調里,給DOM里的圖片src賦值就行了。

當然,如果不兼容ie9,現在這個方案就行了。

在ie9下,不支持FormData。所以在ie9下,只能通過form表單形式實現圖片上傳。

2. ie9下通過form表單實現圖片上傳

<form id="myForm" method="post" action="/image/ieupload" enctype="multipart/form-data">

  <input name="file" type="file" @change="update" accept="image/x-png, image/jpg, image/jpeg">

  <input id="submit" type="submit" style="display:none">

</form>

form里,enctype必須為mulitpart/form-data,表單中enctype="multipart/form-data"的意思,是設置表單的MIME編碼。默認情況,這個編碼格式是application/x-www-form-urlencoded,不能用于文件上傳;只有使用了multipart/form- data,才能完整的傳遞文件數據。

同時要加上input type="submit",只有點擊(或者trigger click)這個按鈕,才會將數據發送到服務器。

這樣,在上面的update方法里,就需要加一層判斷,如果不是ie9(或者是瀏覽器不支持formData),就通過formData結合ajax實現上傳圖片。通過formData的好處是不用在DOM里寫form,(form表單提交,一般的服務器處理方式是重定向),只通過ajax跟后端服務器交換數據可以讓接口更加統一。而如果是ie9,則必須要通過form表單提交,在update方法里,通過trigger #submit元素的click事件來完成表單提交。

但是,如果服務器返回的是json,并不能拿到服務器返回的數據,而是直接提示下載或打開

ie9下,不能拿到回調

之所以ie9下提示打開或者保持,是因為:
ie無法解析回調里的json數據,就是說如果服務器返回json數據,ie會把它當做文件來處理,顯示打開或保存。

解決方法如下:
在后端返回的時候自定義contype-type為"text/html",比如在node中這樣寫res.setHeader('Content-Type', 'text/html')。
參考資料:文件上傳返回JSON數據,在IE下提示下載文件

這樣改完之后,會發現,雖然現在不提示下載文件了,可是會直接跳轉到新頁面。

ie9下會直接跳轉

在ajax未誕生前,都是用iframe來實現無刷新的效果。為了避免跳轉到新頁面,需要手動指定跳轉的頁面為一個iframe。然后取到iframe里的回調內容后,將相應內容從iframe里取出來使用。

參考資料:通過iframe防止form表單提交時跳轉頁面

另外,由于因為file是Readonly,如果用戶上傳的圖片不符合要求,想清空value,只能用新的file替換之前的file。
參考資料:http://www.cnblogs.com/nsky/archive/2012/12/28/2836578.html

3. 拓展:本地預覽(fileReader)

fileReader就是html5為我們提供的讀取文件的api。它的作用就是把文本流按指定格式讀取到緩存,以供js調用。
參考資料:上傳圖片本地預覽
通過fileReader的readAsDataURL方法,將文件讀取為 DataURL,然后賦值給img的src,就大功告成啦。
DataURL有其固定的格式,如下:
data:[文件格式];base64,[文本流base64編碼]。

img src的值為DataURL格式

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容