IE9 跨域請求相容

發表於2018-05-31

IE9 跨域請求相容

背景

搭建公司官網的框架時採用了 vuejs, 使用 history router mode 來做 SEO 優化, 使用 fetch 做網路請求, fetch 用 whatwg-fetch 做 polyfill. 根據百度瀏覽器市場份額統計, 2017年全年 IE9 的佔有率達到 9.50%, 並且 vue 框架也是相容到 IE9, 所以專案要求相容到 IE9.

但是 fetch polyfill 並不相容 IE9, 這篇文章追溯問題原因並提出解決方法.

問題: 訪問拒絕

在 IE9 下開啟頁面, 發現 fetch 請求報了Unhandled promise rejectionError: 拒絕訪問:

  • IE9
    訪問拒絕
  • IE11 開 IE9 除錯模式
    訪問拒絕

懷疑是 fetch 的相容問題, 檢視一下版本:

檢視了一下whatwg-fetch 相容性: 只支援到 IE10. 然後看到 whatwg-fetchv0.11 可以相容 IE9, 那就降級一下吧:

再試一下, 發現還是一樣的問題.

問題原因: IE9 XMLHttpRequest 不支援 CORS

fetch 的 polyfill 採用了 XMLHttpRequest 實現, 但是在 IE9 下面, XMLHttpRequest 是不支援跨域請求的. IE10 的 XMLHttpRequest 支援跨域, 而 IE8, IE9 需要使用 XDomainRequest 來實現跨域.

那就用 XDomainRequest 實現非同步請求, 程式碼:

需要注意的是:

  • XDomainRequest 只支援 GET 和 POST mehtod
  • XDomainRequest 不支援帶 cookie
  • XDomainRequest 不能設定 responseType, 通訊雙方需要約定資料格式
  • XDomainRequest 的響應沒有 response status code

題外話: whatwg-fetch 一直採用 XMLHttpRequest 來做 polyfill, whatwg-fetch1.0+ 不支援 IE9, 並不是因為沒有采用 XDomainRequest, 而是因為 IE9 的狀態碼不符合 fetch 規範, 而 polyfill 的目標是 polyfill 規範, 而不是做相容.

問題: 請求異常終止和掛起

寫好了程式碼, 在 IE9 中, 網路請求非常詭異, 經常不行: 請求只持續了不到 1ms, 並且接收資料為 0B, 沒有狀態碼; 但是在少數時候是可以成功請求並獲取資料的.

  • IE9
    異常終止
  • IE11 開 E9 除錯模式
    此時 IE11 的 IE9 除錯模式是可以的, 看來模擬器還是模擬不到位.
    沒有異常終止

查了好久, 終於看到一篇文章: Internet Explorer Aborting AJAX Requests : FIXED

IE timing out the request even though data is being transmitted.

主要的原因大概是 IE9 會將一個正在傳輸的請求 timeout 掉.

解決辦法是:

  • 新增 onprogress 事件回撥, 告知 IE9 這個請求是活動中的, 不要 timeout 掉.
  • 將請求的傳送放到主執行緒之外, 保證 XDomainRequest 已經完全初始化好.

最終程式碼

結論

  • IE9 發起跨域請求要使用 XDomainRequest, 因為 IE9 下的 XMLHttpRequest 不支援跨域呼叫.
  • XDomainRequest 只支援 GET 和 POST method, 並且沒有 response status code, 可以說是不完善的 HTTP 非同步請求物件.
  • XDomainRequest 不支援指定 responseType, 使用時建議請求和返回資料格式約定為 JSON.
  • whatwg-fetch1.0+ 不支援 IE9, 是因為 IE9 的狀態碼不符合 fetch 規範, 而 polyfill 的目標是 polyfill 規範, 而不是做相容.

References

  • XDomainRequest

https://developer.mozilla.org/en-US/docs/Web/API/XDomainRequest

  • XMLHttpRequest

https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

  • XDomainRequest – Restrictions, Limitations and Workarounds

https://blogs.msdn.microsoft.com/ieinternals/2010/05/13/xdomainrequest-restrictions-limitations-and-workarounds/

  • Internet Explorer Aborting AJAX Requests : FIXED

https://cypressnorth.com/programming/internet-explorer-aborting-ajax-requests-fixed/

相關文章