【问题标题】:ExtJs 5.0.1: Synchronus Ajax request in FirefoxExtJs 5.0.1:Firefox 中的同步 Ajax 请求
【发布时间】:2014-12-05 12:37:23
【问题描述】:

在项目中,我们有一个 config 单例对象,它保存从服务器 (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;
        };
    }
});

在构造函数中,我们有一个 closure,它在 synchrone Ajax 请求服务器配置对象之后保存。 我们需要发出一个同步请求,因为在其他各种类中都需要服务器配置值来提供在创建之前的配置。 通过 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')
});

但是当我们在类定义中访问 c​​onfig 对象中的单例时,服务器配置单例在 Firefox 中始终没有实例化。在 ChromeInternet Explorer 8+ 中,它按预期工作

为了确保我们已经准备好使用单例,我们尝试了以下方法。我们在 Ext.require 的回调中移动了应用程序定义。但这并不能解决 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.

因此,同步请求将在未来被删除,并且只允许在 webworkers 中使用。 我们需要一个解决方案。

问题只发生在开发者模式,当我们用sencha app build构建它时,它在Firefox中工作强>...

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

更新 index.html -> index.php

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

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

【问题讨论】:

    标签: ajax extjs xmlhttprequest extjs5


    【解决方案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 和您的应用程序加载之前直接将您的配置作为 JSON 输出到 HTML 页面。

    【讨论】:

    • 感谢您的这种方法,如果这适用于我们的项目,我会尝试。
    【解决方案2】:

    试试这个:

    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 可能没有通过要求加载。通过在构造函数中调用它,您可以确定所有要求都已满足,因此它应该可用。

    【讨论】:

    • 是的,我们考虑过这一点,但是当我们有包含很多项目的组件并且这些项目还需要来自 serverConfig 的一些值时,很难调整此代码。同样,当 xhr 中的同步标志被删除时,我们也会遇到同样的问题,因为我们首先需要 serverConfig 单格中的数据,然后我们可以使用 gettter/setter 函数访问它们。
    猜你喜欢
    • 1970-01-01
    • 2020-04-24
    • 2023-04-01
    • 1970-01-01
    • 2012-02-28
    • 2011-09-08
    • 1970-01-01
    • 2019-09-04
    • 1970-01-01
    相关资源
    最近更新 更多