uni_app下的html多语言引用及iOS无用的问题

html多语言的方法,百度即可获得,这里不多说了。
iOS下,ajax不能用,可以看这个https://ask.dcloud.net.cn/article/36858。这个方法写在调用多语言之前即可。
下面关键点来了,按照上面方法配置完成。用苹果手机测试时,会报错:编码错误。查找论坛,发现需要在路径前面加上 file:// ,加过之后开始报其他错误:不允许读。经过多番尝试,好像是路径不对。于是我想起使用 plus.io.convertLocalFileSystemURL 来拼接全路径,经过测试,iOS也可以了。
但是还是有一个问题,plus.io.resolveLocalFileSystemURL是异步。国际化获取值需要想获取完数据才可以,于是我修改了一下jquery.i18n.properties.js文件。

$.i18n.properties = async function(settings) {
        // set up settings
        var defaults = {
            name: 'Messages',
            language: '',
            path: '',
            mode: 'vars',
            cache: false,
            encoding: 'UTF-8',
            callback: null
        };
        settings = $.extend(defaults, settings);
        if (settings.language === null || settings.language == '') {
            settings.language = $.i18n.browserLang();
        }
        if (settings.language === null) {
            settings.language = '';
        }

        // load and parse bundle files
        var files = getFiles(settings.name);
        for (i = 0; i < files.length; i++) {
            
                await loadAndParseFile(settings.path + files[i] + '_' + settings.language + '.properties', settings);
            // // 1. load base (eg, Messages.properties)
            // loadAndParseFile(settings.path + files[i] + '.properties', settings);
            // // 2. with language code (eg, Messages_pt.properties)
            // if (settings.language.length >= 2) {
            //  loadAndParseFile(settings.path + files[i] + '_' + settings.language.substring(0, 2) + '.properties', settings);
            // }
            // // 3. with language code and country code (eg, Messages_pt_PT.properties)
            // if (settings.language.length >= 5) {
            //  loadAndParseFile(settings.path + files[i] + '_' + settings.language.substring(0, 5) + '.properties', settings);
            // }
        }

        // call callback
        if (settings.callback) {
            settings.callback();
        }
    };

使用async和await完成同步。

此外,为了是iOS和安卓一致,对my-xmlhttprequest.js文件也进行了修改。在fXMLHttpRequest_send方法中对路径进行优化

function fXMLHttpRequest_send(oRequest) {
        oRequest.readyState = MyXmlHttpRequest.OPENED;
        var path = "file://" + plus.io.convertLocalFileSystemURL(oRequest.url);
        plus.io.resolveLocalFileSystemURL(path, function(entry) {
            entry.file( function(file) {

                var fileReader = new plus.io.FileReader();
                fileReader.readAsText(file, 'utf-8');
                fileReader.onloadend = function(evt) {
                    //console.log("evt.target.result: " + evt.target.result);
                    
                    oRequest.readyState = 4;
                    var responseText = evt.target.result;
                    var parser = new DOMParser();
                    var responseXML = parser.parseFromString(responseText, 'text/xml');
                    //console.log('responseText: ' + responseText);
                    oRequest.fChangeValues(responseText, responseXML, 200, 'success');
                    if (oRequest.onload) {
                        console.log('xmlhttprequest callback onload');
                        oRequest.onload();
                    }
                    fReadyStateChange(oRequest);
                }
            });
            
        }, function (e) {
            console.log("Resolve file URL failed: " + e.message);
            
            oRequest.readyState = 4;
            oRequest.fChangeValues('', null, 404, 'error');

            if (oRequest.onerror) {
                console.log('xmlhttprequest callback onerror');
                oRequest.onerror();
            }

            fReadyStateChange(oRequest);
        }); 
    }

这样问题就解决了。

下面附上改过的jquery.i18n.properties.js和my-xmlhttprequest.js文件
jquery.i18n.properties.js


(function() {

    function MyXmlHttpRequest() {
        this._listeners = [];
    }
    
    MyXmlHttpRequest.UNSENT            = 0;
    MyXmlHttpRequest.OPENED            = 1;
    MyXmlHttpRequest.HEADERS_RECEIVED  = 2;
    MyXmlHttpRequest.LOADING           = 3;
    MyXmlHttpRequest.DONE              = 4;

    // Interface level constants
    MyXmlHttpRequest.prototype.UNSENT            = MyXmlHttpRequest.UNSENT;
    MyXmlHttpRequest.prototype.OPENED            = MyXmlHttpRequest.OPENED;
    MyXmlHttpRequest.prototype.HEADERS_RECEIVED  = MyXmlHttpRequest.HEADERS_RECEIVED;
    MyXmlHttpRequest.prototype.LOADING           = MyXmlHttpRequest.LOADING;
    MyXmlHttpRequest.prototype.DONE              = MyXmlHttpRequest.DONE;

    // Public Properties
    MyXmlHttpRequest.prototype.readyState    = MyXmlHttpRequest.UNSENT;
    MyXmlHttpRequest.prototype.responseText  = '';
    MyXmlHttpRequest.prototype.responseXML   = null;
    MyXmlHttpRequest.prototype.status        = 0;
    MyXmlHttpRequest.prototype.statusText    = '';

    // Priority proposal
    MyXmlHttpRequest.prototype.priority    = "NORMAL";

    MyXmlHttpRequest.prototype.method = '';
    MyXmlHttpRequest.prototype.url = '';
    MyXmlHttpRequest.prototype.async = true;
    MyXmlHttpRequest.prototype.user = '';
    MyXmlHttpRequest.prototype.password = '';

    // Instance-level Events Handlers
    MyXmlHttpRequest.prototype.onreadystatechange  = null;

    // Class-level Events Handlers
    MyXmlHttpRequest.onreadystatechange  = null;
    MyXmlHttpRequest.onopen              = null;
    MyXmlHttpRequest.onsend              = null;
    MyXmlHttpRequest.onabort             = null;
    MyXmlHttpRequest.onload              = null;
    MyXmlHttpRequest.onerror             = null;

    // Public Methods
    MyXmlHttpRequest.prototype.open  = function(sMethod, sUrl, bAsync, sUser, sPassword) {
        // http://www.w3.org/TR/XMLHttpRequest/#the-open-method
        var sLowerCaseMethod = sMethod.toLowerCase();
        if (sLowerCaseMethod == "connect" || sLowerCaseMethod == "trace" || sLowerCaseMethod == "track") {
            throw new Error(18);
        }

        delete this._headers;

        this.method   = sMethod;
        this.url      = sUrl;
        this.async    = bAsync;
        this.user     = sUser;
        this.password = sPassword;

        if (MyXmlHttpRequest.onopen) {
            MyXmlHttpRequest.onopen.apply(this, arguments);
        }

        this.readyState = MyXmlHttpRequest.OPENED;
        fReadyStateChange(this);
    };

    MyXmlHttpRequest.prototype.send = function(vData) {
        // Add method sniffer
        if (MyXmlHttpRequest.onsend) {
            MyXmlHttpRequest.onsend.apply(this, arguments);
        }

        if (!arguments.length) {
            vData = null;
        }

        if (vData && vData.nodeType) {
            vData = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
            if (!this._headers["Content-Type"]) {
                this.setRequestHeader("Content-Type", "application/xml");
            }
        }

        this._data = vData;

        fXMLHttpRequest_send(this);
    };

    MyXmlHttpRequest.prototype.abort = function() {
        if (MyXmlHttpRequest.onabort) {
            MyXmlHttpRequest.onabort.apply(this, arguments);
        }

        if (this.readyState > MyXmlHttpRequest.UNSENT) {
            this._aborted = true;
        }

        fCleanTransport(this);

        this.readyState = MyXmlHttpRequest.UNSENT;
        delete this._data;
    };

    MyXmlHttpRequest.prototype.getAllResponseHeaders = function() {
        return null;
    };

    MyXmlHttpRequest.prototype.getResponseHeader = function(sName) {
        return null;
    };

    MyXmlHttpRequest.prototype.setRequestHeader  = function(sName, sValue) {
        if (!this._headers) {
            this._headers = {};
        }

        this._headers[sName]  = sValue;
    };

    MyXmlHttpRequest.prototype.addEventListener  = function(sName, fHandler, bUseCapture) {
        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
            if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
                return;
            }
        }

        // Add listener
        this._listeners.push([sName, fHandler, bUseCapture]);
    };

    MyXmlHttpRequest.prototype.removeEventListener = function(sName, fHandler, bUseCapture) {
        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
            if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
                break;
            }
        }

        // Remove listener
        if (oListener) {
            this._listeners.splice(nIndex, 1);
        }
    };

    MyXmlHttpRequest.prototype.dispatchEvent = function(oEvent) {
        var oEventPseudo  = {
            'type':             oEvent.type,
            'target':           this,
            'currentTarget':    this,
            'eventPhase':       2,
            'bubbles':          oEvent.bubbles,
            'cancelable':       oEvent.cancelable,
            'timeStamp':        oEvent.timeStamp,
            'stopPropagation':  function() {},  // There is no flow
            'preventDefault':   function() {},  // There is no default action
            'initEvent':        function() {}   // Original event object should be initialized
        };

        // Execute onreadystatechange
        if (oEventPseudo.type == "readystatechange" && this.onreadystatechange) {
            (this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);
        }


        // Execute listeners
        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
            if (oListener[0] == oEventPseudo.type && !oListener[2]) {
                (oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);
            }
        }

    };

    MyXmlHttpRequest.prototype.toString  = function() {
        return '[' + "object" + ' ' + "MyXmlHttpRequest" + ']';
    };

    MyXmlHttpRequest.toString  = function() {
        return '[' + "MyXmlHttpRequest" + ']';
    };

    MyXmlHttpRequest.prototype.fChangeValues = function(responseText, responseXML, status, statusText) {
        this.responseText = responseText;
        this.responseXML  = responseXML;
        this.status       = status;
        this.statusText   = statusText;
    }

    // Helper function
    function fXMLHttpRequest_send(oRequest) {
        oRequest.readyState = MyXmlHttpRequest.OPENED;
        var path = "file://" + plus.io.convertLocalFileSystemURL(oRequest.url);
        console.log(path);
        plus.io.resolveLocalFileSystemURL(path, function(entry) {
            entry.file( function(file) {

                var fileReader = new plus.io.FileReader();
                fileReader.readAsText(file, 'utf-8');
                fileReader.onloadend = function(evt) {
                    //console.log("evt.target.result: " + evt.target.result);
                    
                    oRequest.readyState = 4;
                    var responseText = evt.target.result;
                    var parser = new DOMParser();
                    var responseXML = parser.parseFromString(responseText, 'text/xml');
                    //console.log('responseText: ' + responseText);
                    oRequest.fChangeValues(responseText, responseXML, 200, 'success');
                    if (oRequest.onload) {
                        console.log('xmlhttprequest callback onload');
                        oRequest.onload();
                    }
                    fReadyStateChange(oRequest);
                }
            });
            
        }, function (e) {
            console.log("Resolve file URL failed: " + e.message);
            
            oRequest.readyState = 4;
            oRequest.fChangeValues('', null, 404, 'error');

            if (oRequest.onerror) {
                console.log('xmlhttprequest callback onerror');
                oRequest.onerror();
            }

            fReadyStateChange(oRequest);
        }); 
    }

    function fReadyStateChange(oRequest) {
        // Sniffing code
        if (MyXmlHttpRequest.onreadystatechange){
            MyXmlHttpRequest.onreadystatechange.apply(oRequest);
        }

        // Fake event
        oRequest.dispatchEvent({
            'type':       "readystatechange",
            'bubbles':    false,
            'cancelable': false,
            'timeStamp':  new Date().getTime()
        });
    }

    function fCleanTransport(oRequest) {
        //
    }

    if (!window.Function.prototype.apply) {
        window.Function.prototype.apply = function(oRequest, oArguments) {
            if (!oArguments) {
                oArguments  = [];
            }
            oRequest.__func = this;
            oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
            delete oRequest.__func;
        };
    }

    window.MyXmlHttpRequest = MyXmlHttpRequest;

})();

my-xmlhttprequest.js


(function() {

    function MyXmlHttpRequest() {
        this._listeners = [];
    }
    
    MyXmlHttpRequest.UNSENT            = 0;
    MyXmlHttpRequest.OPENED            = 1;
    MyXmlHttpRequest.HEADERS_RECEIVED  = 2;
    MyXmlHttpRequest.LOADING           = 3;
    MyXmlHttpRequest.DONE              = 4;

    // Interface level constants
    MyXmlHttpRequest.prototype.UNSENT            = MyXmlHttpRequest.UNSENT;
    MyXmlHttpRequest.prototype.OPENED            = MyXmlHttpRequest.OPENED;
    MyXmlHttpRequest.prototype.HEADERS_RECEIVED  = MyXmlHttpRequest.HEADERS_RECEIVED;
    MyXmlHttpRequest.prototype.LOADING           = MyXmlHttpRequest.LOADING;
    MyXmlHttpRequest.prototype.DONE              = MyXmlHttpRequest.DONE;

    // Public Properties
    MyXmlHttpRequest.prototype.readyState    = MyXmlHttpRequest.UNSENT;
    MyXmlHttpRequest.prototype.responseText  = '';
    MyXmlHttpRequest.prototype.responseXML   = null;
    MyXmlHttpRequest.prototype.status        = 0;
    MyXmlHttpRequest.prototype.statusText    = '';

    // Priority proposal
    MyXmlHttpRequest.prototype.priority    = "NORMAL";

    MyXmlHttpRequest.prototype.method = '';
    MyXmlHttpRequest.prototype.url = '';
    MyXmlHttpRequest.prototype.async = true;
    MyXmlHttpRequest.prototype.user = '';
    MyXmlHttpRequest.prototype.password = '';

    // Instance-level Events Handlers
    MyXmlHttpRequest.prototype.onreadystatechange  = null;

    // Class-level Events Handlers
    MyXmlHttpRequest.onreadystatechange  = null;
    MyXmlHttpRequest.onopen              = null;
    MyXmlHttpRequest.onsend              = null;
    MyXmlHttpRequest.onabort             = null;
    MyXmlHttpRequest.onload              = null;
    MyXmlHttpRequest.onerror             = null;

    // Public Methods
    MyXmlHttpRequest.prototype.open  = function(sMethod, sUrl, bAsync, sUser, sPassword) {
        // http://www.w3.org/TR/XMLHttpRequest/#the-open-method
        var sLowerCaseMethod = sMethod.toLowerCase();
        if (sLowerCaseMethod == "connect" || sLowerCaseMethod == "trace" || sLowerCaseMethod == "track") {
            throw new Error(18);
        }

        delete this._headers;

        this.method   = sMethod;
        this.url      = sUrl;
        this.async    = bAsync;
        this.user     = sUser;
        this.password = sPassword;

        if (MyXmlHttpRequest.onopen) {
            MyXmlHttpRequest.onopen.apply(this, arguments);
        }

        this.readyState = MyXmlHttpRequest.OPENED;
        fReadyStateChange(this);
    };

    MyXmlHttpRequest.prototype.send = function(vData) {
        // Add method sniffer
        if (MyXmlHttpRequest.onsend) {
            MyXmlHttpRequest.onsend.apply(this, arguments);
        }

        if (!arguments.length) {
            vData = null;
        }

        if (vData && vData.nodeType) {
            vData = window.XMLSerializer ? new window.XMLSerializer().serializeToString(vData) : vData.xml;
            if (!this._headers["Content-Type"]) {
                this.setRequestHeader("Content-Type", "application/xml");
            }
        }

        this._data = vData;

        fXMLHttpRequest_send(this);
    };

    MyXmlHttpRequest.prototype.abort = function() {
        if (MyXmlHttpRequest.onabort) {
            MyXmlHttpRequest.onabort.apply(this, arguments);
        }

        if (this.readyState > MyXmlHttpRequest.UNSENT) {
            this._aborted = true;
        }

        fCleanTransport(this);

        this.readyState = MyXmlHttpRequest.UNSENT;
        delete this._data;
    };

    MyXmlHttpRequest.prototype.getAllResponseHeaders = function() {
        return null;
    };

    MyXmlHttpRequest.prototype.getResponseHeader = function(sName) {
        return null;
    };

    MyXmlHttpRequest.prototype.setRequestHeader  = function(sName, sValue) {
        if (!this._headers) {
            this._headers = {};
        }

        this._headers[sName]  = sValue;
    };

    MyXmlHttpRequest.prototype.addEventListener  = function(sName, fHandler, bUseCapture) {
        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
            if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
                return;
            }
        }

        // Add listener
        this._listeners.push([sName, fHandler, bUseCapture]);
    };

    MyXmlHttpRequest.prototype.removeEventListener = function(sName, fHandler, bUseCapture) {
        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
            if (oListener[0] == sName && oListener[1] == fHandler && oListener[2] == bUseCapture) {
                break;
            }
        }

        // Remove listener
        if (oListener) {
            this._listeners.splice(nIndex, 1);
        }
    };

    MyXmlHttpRequest.prototype.dispatchEvent = function(oEvent) {
        var oEventPseudo  = {
            'type':             oEvent.type,
            'target':           this,
            'currentTarget':    this,
            'eventPhase':       2,
            'bubbles':          oEvent.bubbles,
            'cancelable':       oEvent.cancelable,
            'timeStamp':        oEvent.timeStamp,
            'stopPropagation':  function() {},  // There is no flow
            'preventDefault':   function() {},  // There is no default action
            'initEvent':        function() {}   // Original event object should be initialized
        };

        // Execute onreadystatechange
        if (oEventPseudo.type == "readystatechange" && this.onreadystatechange) {
            (this.onreadystatechange.handleEvent || this.onreadystatechange).apply(this, [oEventPseudo]);
        }


        // Execute listeners
        for (var nIndex = 0, oListener; oListener = this._listeners[nIndex]; nIndex++) {
            if (oListener[0] == oEventPseudo.type && !oListener[2]) {
                (oListener[1].handleEvent || oListener[1]).apply(this, [oEventPseudo]);
            }
        }

    };

    MyXmlHttpRequest.prototype.toString  = function() {
        return '[' + "object" + ' ' + "MyXmlHttpRequest" + ']';
    };

    MyXmlHttpRequest.toString  = function() {
        return '[' + "MyXmlHttpRequest" + ']';
    };

    MyXmlHttpRequest.prototype.fChangeValues = function(responseText, responseXML, status, statusText) {
        this.responseText = responseText;
        this.responseXML  = responseXML;
        this.status       = status;
        this.statusText   = statusText;
    }

    // Helper function
    function fXMLHttpRequest_send(oRequest) {
        oRequest.readyState = MyXmlHttpRequest.OPENED;
        var path = "file://" + plus.io.convertLocalFileSystemURL(oRequest.url);
        console.log(path);
        plus.io.resolveLocalFileSystemURL(path, function(entry) {
            entry.file( function(file) {

                var fileReader = new plus.io.FileReader();
                fileReader.readAsText(file, 'utf-8');
                fileReader.onloadend = function(evt) {
                    //console.log("evt.target.result: " + evt.target.result);
                    
                    oRequest.readyState = 4;
                    var responseText = evt.target.result;
                    var parser = new DOMParser();
                    var responseXML = parser.parseFromString(responseText, 'text/xml');
                    //console.log('responseText: ' + responseText);
                    oRequest.fChangeValues(responseText, responseXML, 200, 'success');
                    if (oRequest.onload) {
                        console.log('xmlhttprequest callback onload');
                        oRequest.onload();
                    }
                    fReadyStateChange(oRequest);
                }
            });
            
        }, function (e) {
            console.log("Resolve file URL failed: " + e.message);
            
            oRequest.readyState = 4;
            oRequest.fChangeValues('', null, 404, 'error');

            if (oRequest.onerror) {
                console.log('xmlhttprequest callback onerror');
                oRequest.onerror();
            }

            fReadyStateChange(oRequest);
        }); 
    }

    function fReadyStateChange(oRequest) {
        // Sniffing code
        if (MyXmlHttpRequest.onreadystatechange){
            MyXmlHttpRequest.onreadystatechange.apply(oRequest);
        }

        // Fake event
        oRequest.dispatchEvent({
            'type':       "readystatechange",
            'bubbles':    false,
            'cancelable': false,
            'timeStamp':  new Date().getTime()
        });
    }

    function fCleanTransport(oRequest) {
        //
    }

    if (!window.Function.prototype.apply) {
        window.Function.prototype.apply = function(oRequest, oArguments) {
            if (!oArguments) {
                oArguments  = [];
            }
            oRequest.__func = this;
            oRequest.__func(oArguments[0], oArguments[1], oArguments[2], oArguments[3], oArguments[4]);
            delete oRequest.__func;
        };
    }

    window.MyXmlHttpRequest = MyXmlHttpRequest;

})();

你可能感兴趣的:(uni_app下的html多语言引用及iOS无用的问题)