Javascript Web应用程序最佳实践

Javascript Web App Best Practices

本文关键字:最佳 应用程序 Web Javascript      更新时间:2023-09-26

我很难简明扼要地写下我的问题,所以让我描述一下我正在处理的问题。

我正在构建一个web应用程序:

  • 有自己的API托管在子域(https://api.example.com)
  • 使主应用程序托管在tld (https://www.example.com)
  • tld没有任何数据库访问,而是与API交互以处理数据
  • tld通过OAuth与api进行身份验证,并将访问令牌和访问令牌机密存储在会话中
    • 会话结束时,不再使用访问令牌,从而将用户注销

我在tld中有一个路由(对于这个问题,我们称之为/ajax),javascript调用它(GETPUTPOSTDELETE)来向api发出请求。通过这种方式,任何人都不必查看访问令牌、访问令牌机密、使用者密钥或使用者机密。

在我看来,访问令牌和访问令牌秘密实际上是我在会话中唯一需要存储的东西,因为我可以使用API获取其他所有东西,但我认为有些东西应该持久存在,比如用户配置文件、布局首选项等

对我来说,实现这一目标的最佳方式是什么?本地存储?饼干?我应该废弃这个并将其存储在会话中吗

如果你有时间的话,对于这样的建筑工地,还有什么我可能不知道的最佳实践

我想说,您走在了正确的轨道上,但主要将数据存储在JavaScript中。并在适当的时候将其与本地存储相结合。

当我构建像您所描述的应用程序时,我通常会注意设置通过API接收的数据的JavaScript表示。

一种这样的表述可以如下所示。请记住,我下面的示例代码做了几个假设。

  1. 它假设您定义了一个api对象,该对象负责API调用,并在完成时调用回调
  2. API返回的数据是JSON,其可以简单地分配给JavaScript变量
  3. 返回的JSON是一个对象列表,每个对象都有一个"id"字段
  4. 如果您有某种事件对象,我通常会构建自己的自定义事件,这些事件基本上携带function对象作为侦听器,并且在触发时通过侦听器并根据情况调用带有或不带有有效负载的函数

数据容器示例:

MYAPP.data.BaseContainer = function (api_url, loadedEvent) {
    var self = {
        // Array to store the data returned via the APIs 
        _data : [],
        // The API URL used to fetch data
        api_url : api_url,
        // Boolean flag to signify whether the _data variable has been populated
        is_loaded : false,
        // The even to fire once _data has been populated
        loadedEvent : loadedEvent,
        /**
         * Returns the state of the is_loaded variable
         */
        loaded : function () {
            return self.is_loaded;
        },
        /**
         * Takes an ID and returns any member of the _data array
         * that has that ID.
         * 
         * @param id : an String or integer representing the ID.
         * @returns {Object}
         */
        byId : function (id) {
            var toReturn = null;
            for (var i = 0, len = self._data.length; i < len; i++) {
                if (self._data[i].id == id) {
                    toReturn = self._data[i];
                    break;
                }
            }
            return toReturn; 
        },
        /**
         * Returns the entire _data array.
         */
        all : function () {
            return self._data;
        },
        /**
         * This simple callback just stores the json response in 
         * its entirety on the _data variable.
         */
        callback : function(data) {
            self._data = data;
            self.is_loaded = true;
            loadedEvent.fire(self._data);
        },
        /**
         * Calls the API, if no callback has been specified as a parameter
         * self.callback is used.
         */
        getFromAPI : function(callback) {
            if (typeof callback === 'undefined') {
                callback = self.callback;
            }
            api.get(self.api_url, callback);
        }
    };
    self.getFromAPI();
    return self;
};

有了这个蓝图,我现在可以创建这样的特定数据容器:

/**
 * Stores a list of "friends" gotten from the API.
 * This is basically an instance of the BaseContainer object defined above.
 */
MYAPP.data.Friends = (function () {
    var self = MYAPP.data.BaseContainer("API_URL_TO_FECTH_FRIENDS_LIST", FriendsLoadedEvent);
    return {
        byId : self.byId,
        all : self.all,
        loaded : self.loaded
    };
}());

一旦运行此代码,就会进行API调用,并在调用完成后激发FriendsLoadedEvent。所以,坦率地说,我通常使用JavaScript来存储我的东西。但如果你想把LocalStorage加入其中,那也很容易!

只需将本地存储代码添加到BaseContainer对象中,该对象首先检测客户端是否真正支持本地存储,如果支持,则镜像本地存储中的_data字段。这样可以方便地在会话之间保持经常使用的数据的快速可用性。使用现成的JSON解析工具将数据从JSON转换为LocalStorage"文本"并返回。

请记住,您不能依赖LocalStorage作为主要数据结构,您不能保证客户端支持它,即使它支持它,浏览器之间实际可以存储的数据量的上限也不同。因此,使用它来存储以下数据:

  • 您希望经常访问
  • 用户一登录,你就觉得应该立即出现在那里
  • 并且其变化的频率不足以保证不断刷新API调用

祝贺!你已经回答了大部分问题。如果你想持久保存用户数据,你需要使用本地存储或cookie之类的东西。在您的情况下,本地存储是最好的。使用cookie,每个页面请求都会发送到标头中的cookie。

祝你的应用程序好运。

相关文章: