ExtJs 5.0.1:Firefox中的同步Ajax请求

时间:2014-12-05 12:37:23

标签: ajax extjs xmlhttprequest extjs5

在项目中,我们有一个配置单件对象,它保存从服务器获取的配置(ServerConfig)。它被定义为

Ext.define('SI.ServerConfig', {
    singleton: true,
    constructor: function () {
        this.callParent(arguments);

        // Closure which holds the serverConfig after the synchronus request
        var serverConfig;

        Ext.Ajax.request({
            url: 'example.de/getConfig.php',
            method: 'POST',
            async: false,
            success: function(response){
                var responseObj = Ext.JSON.decode(response.responseText);
                serverConfig = responseObj.serverConfig;
            }
        });

        //definition of setter/getter function for the serverConfig closure
        this.get = function (optionName, defaultVal) {
            if (Ext.isDefined(serverConfig[optionName])){
                return serverConfig[optionName];
            }

            return defaultVal;
        };


        this.set = function (optionName, value) {
            serverConfig[optionName] = value;
        };
    }
});

在构造函数中,我们有一个闭包,它在同步Ajax请求服务器配置对象之后保留。 我们需要发出同步请求,因为在各种其他类中需要服务器配置值来提供配置bevore创建。 使用setter和getter函数,我们可以访问其中定义的值。在每个控制器/视图/模型中,我们需要访问服务器配置,我们需要单例。

Ext.define('SI.view.TestView', {
    extends: 'Ext.panel.Panel',
    requires: ['SI.ServerConfig'],

    // This fails most of the time in Firefox, but works every time in Chrome and IE 8+
    title: SI.ServerConfig.get('testTitle')
});

但是当我们在类定义中访问config对象中的单例时,服务器配置单例不会一直在Firefox 中实例化。在 Chrome Internet Explorer 8 + 中,按预期正常工作

因此,为了避免我们准备使用单身人士,我们尝试了以下方法。我们在Ext.require的回调中移动了Application定义。但这并不适用于Firefox。

Ext.require([
    'SI.ServerConfig'
], function () {
    Ext.define('SI.Application', {
      // ....
    }); /
}); 

在Firefox调试器中记录以下内容:

Synchrone XMLHttpRequests am Haupt-Thread sollte nicht mehr verwendet werden, 
weil es nachteilige Effekte für das Erlebnis der Endbenutzer hat.
Für weitere Hilfe siehe http://xhr.spec.whatwg.org/

来自XHR spezification

Synchronous XMLHttpRequest outside of workers is in the process of being 
removed from the web platform as it has detrimental effects to the end 
user's experience. (This is a long process that takes many years.) 

Developers must not pass false for the async argument when the JavaScript 
global environment is a document environment. User agents are strongly 
encouraged to warn about such usage in developer tools and may experiment with 
throwing anInvalidAccessError exception when it occurs.

因此,将来会删除同步请求,并且只允许在网络工作者中使用。 我们需要一个解决方案。

问题仅在开发者模式中出现,当我们使用 sencha app build 构建时,在Firefox中运行强> ...

感谢您的任何建议。 和-γ

更新index.html - >的index.php

我将index.html改为index.php,就像@colinramsay建议的那样,并且在包含microloader之前包含了服务器配置对象。 现在关于Synchrone XMLHttpRequests的警告在Firefox中消失了。

但是,在类定义中访问配置对象中的单例时,问题仍然存在于Firefox中。

2 个答案:

答案 0 :(得分:1)

试试这个:

Ext.define('SI.view.TestView', {
    extends: 'Ext.panel.Panel',
    requires: ['SI.ServerConfig'],

    constructor: function() {
        this.callParent();
        this.setTitle(SI.ServerConfig.get('testTitle'));
    }
});

我怀疑这是一个加载订单问题。在原始代码中,Ext.define将在需要启动之前同时运行SI.ServerConfig,因此SI.ServerConfig可能没有通过requires加载。通过在构造函数中调用它,您可以确保已满足所有要求,因此它应该可用。

答案 1 :(得分:1)

另一种完全不同的方法是将应用程序的根index.html更改为index.php,它执行以下操作:

<!DOCTYPE HTML>
<html manifest="">
    <head> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta charset="UTF-8">

    <title></title>

    <script type="text/javascript">
        var SI = {};
        <?php
        echo 'SI.ServerConfig = { "testTitle": "some string" }'; 
        ?>
    </script>

    <!-- The line below must be kept intact for Sencha Cmd to build your application -->
    <script id="microloader" type="text/javascript" src="bootstrap.js"></script>

</head>
<body></body>
</html>

这允许您将获取代码更改为:

function get(optionName, defaultVal) {
    if (Ext.isDefined(SI.ServerConfig[optionName])){
        return SI.ServerConfig[optionName];
    }

    return defaultVal;
}

您正在使用PHP在Ext JS和应用程序加载之前将配置直接输出到HTML页面作为JSON。