摘要:[Android] WebView內的本地網頁,使用XMLHttpRequest讀取本地檔案
[Android] WebView內的本地網頁,使用XMLHttpRequest讀取本地檔案
問題情景
在Android裡,可以使用WebView來呈現本地或是遠端的網頁內容。但是在顯示本地網頁時,如果開發人員在網頁裡使用了XMLHttpRequest來額外載入本地檔案(ex:AngularJS裡Route功能的TemplateURL),在部分手機上會呈現下列的錯誤訊息:
Failed to execute 'send' on 'XMLHttpRequest': Failed to load 'file:///android_asset/content.txt'.
發生這個錯誤的原因,是因為Android基於安全性的考量,從Android 4.1版開始禁止了WebView內的本地網頁使用XMLHttpRequest來讀取本地檔案(4.1版之前無限制)。這也就造成了「Android 4.1之前的手機」可以正常使用XMLHttpRequest,而「Android 4.1之後的手機」無法正常使用XMLHttpRequest。
解決方案
為了讓Android 4.1之後的本地網頁,也能正常使用XMLHttpRequest來讀取本地檔案內容。開發人員可以依照下列程式碼的方式,使用WebView原生提供的「AllowFileAccessFromFileURLs」函式,來重新開啟XMLHttpRequest讀取檔案功能,後續在WebView中執行的本地網頁就可以正常使用XMLHttpRequest來讀取本地檔案內容。
-
MainActivity.java
public class MainActivity extends Activity { @SuppressLint({ "SetJavaScriptEnabled", "NewApi" }) @Override protected void onCreate(Bundle savedInstanceState) { // base super.onCreate(savedInstanceState); // content setContentView(R.layout.activity_main); // Browser android.webkit.WebView webView = (WebView)this.findViewById(R.id.webView1); // WebSettings WebSettings settings = webView.getSettings(); settings.setJavaScriptEnabled(true); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { settings.setAllowFileAccessFromFileURLs(true); } // LoadUrl webView.loadUrl("file:///android_asset/index.html"); } }
-
index.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> </head> <body> <h1 id="contentBox"></h1> <script> // ContentBox function display(message) { var contentBox = document.getElementById("contentBox"); contentBox.innerHTML = message; } // XMLHttpRequest var xhr = new XMLHttpRequest(); xhr.onload = function () { display(xhr.responseText); }; try { xhr.open("get", "content.txt", true); xhr.send(); } catch (ex) { display(ex.message); } </script> </body> </html>
範例下載
範例下載:點此下載
參考資料
能以更簡潔的文字與程式碼,傳達出程式設計背後的精神。
真正做到「以形寫神」的境界。