[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>
    

范例下载

范例下载:点此下载

参考数据

posted @ 2015-07-28 12:13  Clark159  阅读(3531)  评论(0编辑  收藏  举报