React在IE9下的檔案上傳方案
阿新 • • 發佈:2019-01-01
存在問題
在IE9上進行檔案上傳主要存在以下問題:
- IE9不支援formdata,也不支援File,所以ajax類提交無效。
- IE9下<input type=’file’/>,不支援mutiple,所以無法多選。
- 傳統表單提交方式會導致頁面重新整理。重新整理的後果就是state丟失,無法進行後續操作。
- IE9不能識別application/json,所以當你通過action提交一個表單,而後臺是返回json時,IE就會把它當成一個檔案下載下來。
解決方案
既然使用不了ajax提交,那麼只能使用傳統表單提交方式。
表單資料提交
其實antd的form.create()的結果也是在頁面上生成了一個<form>,我們可以直接獲取它。
let htmlForm = _this.formArea.getElementsByTagName("form")[0];
獲取到這個form物件後,把它改造成傳統表單。
htmlForm.setAttribute("method", "post"); htmlForm.setAttribute("enctype", "multipart/form-data"); htmlForm.setAttribute("action", serviceUrl + 'ws/uploadHtml?token=' + loginUser().token);
上面程式碼指定了表單傳遞的方法、編碼、及後臺響應地址。接下來處理我們要傳遞的值。首先定義了個公用方法,用於新增表單值。
function addInputElement(htmlForm, name, value) { let input = document.createElement("input"); input.setAttribute("name", name); input.setAttribute("type", "hidden"); input.setAttribute("value", value); htmlForm.appendChild(input); }
新增表單值
addInputElement(htmlForm, 'editableName', values.editableName); addInputElement(htmlForm, 'ajbs', _this.props.ajbs); addInputElement(htmlForm, 'fileType1', values.fileType1);
最後我們只要提交表單即可。
htmlForm.submit();
表單檔案上傳元件
利用html的file標籤實現。該元件我已經寫成公用元件,"rjd": "0.2.25",可使用此元件在ie9下通過傳統模式上傳檔案,並且通過動態增加表單元素的方式解決了ie9不支援multiple的問題。
把它寫在第一步中你的form元件裡,即可在表單提交時提交檔案。
無重新整理頁面
通過將表單的target指向頁面內的iframe,則可以解決頁面重新整理問題。
如可在自定義表單元件後加一個<iframe>
在第一步驟設定表單屬性時增加設定表單target
htmlForm.setAttribute("target", htmlIframe.name);
這樣表單提交時就不會重新整理整個頁面了。
後端介面改造
IE9不能識別application/json,那麼只能改造後端了,後端返回”text/plain”,前端通過JSON.parse進行解析。
後端程式碼示例
前端程式碼解析示例
關鍵參考程式碼
前端(instrument-component\components\wsUpload\uploadForm):
後端(court-splc-web\src\main\java\com\rjsoft\court\splc\web\controller\ws\YswsController.java):