Javascript API cache query non url ?

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par ortolojf, 18 Août 2021.

  1. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 485
    J'aime reçus:
    28
    Bonjour

    Sous Javascript, c'est possible de mettre un objet en cache de cette manière :

    array_param est un objet du type : keys / values.

    fileRequest n'est pas une url.

    Cà ne marche pas car l'API cache impose que la requête commence par http ou https.

    Que faire ?

    Code:
    
        return new Promise(function(resolve, reject) {
          caches.open(cacheName).then(function(CACHE) {
                 CACHE.put(fileRequest, array_param).then(function(result) {
                        // Traitement de result...
                }, {
                    reject( .... );   // open
               })
         }, {
             reject(... );    // put
        })
       }, {
           reject(...);    // Promise
      });
    
    
    
     
  2. rick38
    rick38 WRInaute passionné
    Inscrit:
    23 Février 2013
    Messages:
    1 801
    J'aime reçus:
    273
    L'API CacheStorage ne permet que les URLs, donc utiliser l'API WebStorage avec la méthode localStorage.
     
  3. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 485
    J'aime reçus:
    28
    Bonjour rick38

    Merci beaucoup de ton avis.

    Cependant, l'API Web Storage peut-elle être utilisée dans un service worker ?

    Merci beaucoup.
     
  4. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 485
    J'aime reçus:
    28
    Rebonjour rick38

    Il semblerait ( à partir d'un service worker ), qu'il n'y ait la possibilité que PostMessage et IndexedDB.

    Je vais introspecter. ;)

    Merci beaucoup.
     
  5. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 485
    J'aime reçus:
    28
    Pardon

    Voici un essai avec MessageChannel et PostMessage.

    Le problème consiste à laisser l'initiative au ServiceWorker d'envoyer ses demandes READ/WRITE d'accès au cache, accès gérés en dehors du serviceworker.

    Les fonctions du main thread sont censées être accessibles par le service worker.

    Il suffirait de les dupliquer.

    Voici le code :


    Code:
    
    /*****************************************************************/
    /*                            MAIN THREAD                            **/
    /*****************************************************************/
    const isJson=function(item) {
            item = typeof item !== "string" ? JSON.stringify(item) : item;
            try {
                    item = JSON.parse(item);
            } catch (e) {
                    return false;
            }
            if (typeof item === "object" && item !== null) {
                    return true;
            }
            return false;
    }
    const Type=function(value) {
            if (typeof value === 'undefined') {
                    return 'undefined';
            }
            if(value === null) {
                    return 'null';
            }
            if(typeof value === 'object' &&
                    !Array.isArray(value)) {
                    return 'object';
            }
            if(isJson=(value) {
                    return 'Json';
            }
            if( Array.isArray(value)) {
                    return 'array';
            }
            if(isNaN(value) {
                    return 'NaN';
            }
            if (typeof value === 'boolean') {
                    return 'boolean';
            }
            if (typeof value === 'bigint') {
                    return 'bigint';
            }
            if (typeof value === 'number') {
                    return 'number';
            }
            if (typeof value === 'string' || value instanceof String) {
                    return 'string';
            }
            if !isNaN(Date.parse(value)) {
                    return 'date';
            }
            if (typeof value === 'symbol') {
                    return 'symbol';
            }
            if (typeof value === 'function') {
                    return 'function';
            }
            return 'object';
    }
    Storage.prototype.setObject = function(key, value) {
            var tmp_type = Type(value);
            var tmp_array = ['object', 'array', 'Json', 'symbol'];
            if(tmp_array.indexOf(tmp_type) !== -1) {
                    return this.setItem(key, JSON.stringify(value));
            }
            if(tmp_type === 'function') {
                    return false;
            }
            this.setItem(key, value);
    }
    Storage.prototype.getObject = function(key) {
            var value = this.getItem(key);
            var tmp_type = Type(value);
            var tmp_array = ['object', 'array', 'Json', 'symbol'];
            if(tmp_array.indexOf(tmp_type) !== -1) {
                    return value && JSON.parse(value);
            }
            return value;
    }
    function wrapObjectMessage(str_cache, message, object_message) {
            var array_message = ['READY', 'OK', 'READ', 'WRITE'];
            if(array_message.indexOf(message) == -1) {
                    return false;
            }
            return {'cache': str_cache, 'type': message, 'object_cache': object_message};
    }
    function resObjectMessage(message) {
            var object_message = JSON.parse(message);
            return [object_message.str_cache, object_message.type, object_message.object_cache];
    }
    /*****************************************************/
    /**                  ALGORITHME DE CACHE                **/
    /*****************************************************/
    /**    1)    INITIALISATION    => READY                    **/
    /*****************************************************/
    /**    2) SERVICE WORKER    => ASK READ | WRITE CACHE    **/
    /*****************************************************/
    /**    3) MAIN THREAD        =>    SEND READ CACHE            **/
    /*****************************************************/
    function sendMessage(str_cache, type, object_message) {
            var message = wrapObjectMessage(str_cache, message, object_message);
            // This wraps the message posting/response in a promise, which will resolve if the response doesn't
            // contain an error, and reject with the error if it does. If you'd prefer, it's possible to call
            // controller.postMessage() and set up the onmessage handler independently of a promise, but this is
            // a convenient wrapper.
            return new Promise(function(resolve, reject) {
                    var messageChannel = new MessageChannel();
                    messageChannel.port1.onmessage = function(event) {
                            if (event.data.error) {
                                    reject(event.data.error);
                            } else {
                                    console.log(`Received a message from service Worker: ${event.data}`);
                                    resolve(event.data);
                            }
                    };
                    // This sends the message data as well as transferring messageChannel.port2 to the service worker.
                    // The service worker can then use the transferred port to reply via postMessage(), which
                    // will in turn trigger the onmessage handler on messageChannel.port1.
                    // See https://html.spec.whatwg.org/multipage/workers.html#dom-worker-postmessage
                    navigator.serviceWorker.controller.postMessage(message, [messageChannel.port2]);
            });
    }
    /*********************************/
    /**        MAIN THREAD LISTEN        **/
    /**    SERVICE WORKER MESSAGES    **/
    /*********************************/
    window.addEventListener('message', function(event) {
            var log                = console.log.bind(console);
            var error            = console.error.bind(console);
            var myStorage        = window.localStorage;
            var array_message    = resObjectMessage(event.data);
            var str_cache        = array_message[0];
            var type            = array_message[1];
            var object_message    = null;
            if(['READY', 'OK', 'READ', 'WRITE'].indexOf(type) === -1) {
                    console.log('return type = ' + type);
                    return false;
            }
           
            switch (type) {
                    case 'OK' :
                            break;
                    case 'READ' :
                            /*********************/
                            /**    LECTURE CACHE    **/
                            /*********************/
                            object_message = myStorage.getObject(str_cache);
                            /*************************/
                            /**        ACKNOWLEDGE        **/
                            /**      SERVICE WORKER    **/
                            /*************************/
                            sendMessage(str_cache, type, object_message).then(log, error).catch(error);
                            break;
                    case 'WRITE' :
                            /*********************/
                            /**    ECRITURE CACHE    **/
                            /*********************/
                            object_message = array_message[2];
                            myStorage.setObject(str_cache, object_message);
                            /*************************/
                            /**        ACKNOWLEDGE        **/
                            /**      SERVICE WORKER    **/
                            /*************************/
                            sendMessage(str_cache, type, 'OK').then(log, error).catch(error);
                            break;
                    default :
                            break;
            }
    });
    if ('serviceWorker' in navigator) {
            // Set up a listener for messages posted from the service worker.
            // The service worker is set to post a message to all its clients once it's run its activation
            // handler and taken control of the page, so you should see this message event fire once.
            // You can force it to fire again by visiting this page in an Incognito window.
            navigator.serviceWorker.addEventListener('message', function(event) {
            }
            // Wait until the service worker is active.
            navigator.serviceWorker.register('service-worker.js').then(function() {
                    return navigator.serviceWorker.ready;
            }).then(function() {
                    }).catch(function(error) {
                            // Something went wrong during registration. The service-worker.js file
                            // might be unavailable or contain a syntax error.
                            console.log(error);
                    });
    } else {
            console.log('This browser does not support service workers.');
    }
    /*********************************************************************/
    /*                            SERVICE WORKER                            **/
    /*********************************************************************/
    /*************************************/
    /**        service-worker.js LISTEN    **/
    /**        MAIN THREAD  MESSAGES        **/
    /*************************************/
    var PORT = null;
    self.addEventListener('message', function(event) {
            PORT = event.ports[0];
            console.log(`Received a message from main thread: ${event.data}`);
            var log                = console.log.bind(console);
            var error            = console.error.bind(console);
            var array_message    = resObjectMessage(event.data);
            var str_cache        = array_message[0];
            var type            = array_message[1];
            var object_message    = null;
            if(['READY', 'OK', 'READ', 'WRITE'].indexOf(type) === -1) {
                    console.log('return type = ' + type);
                    return false;
            }
           
            switch (type) {
                    case 'READY' :
                            break;
                    case 'READ' :
                            object_message    = array_message[2];
                            break;
                    case 'WRITE' :
                            /*********************/
                            /**    ECRITURE CACHE    **/
                            /*********************/
                            object_message = array_message[2];
                            if(object_message !== 'OK') {
                                    console.log(`Write message went wrong : ${event.data}`);
                            }
                            break;
                    default :
                            break;
            }
    });
    /*****************************************/
    /**                  EXAMPLES                **/
    /**        ALL ASK FOR READ / WRITE CACHE    **/
    /*****************************************/
    /*****************/
    /**        WRITE    **/
    /*****************/
    var message = wrapObjectMessage(str_cache, 'WRITE', object_to_cache);
    PORT.postMessage(message);
    /*****************/
    /**        READ    **/
    /*****************/
    var message = wrapObjectMessage(str_cache, 'READ', null);
    var message_object = PORT.postMessage(message);
    var array_message = resObjectMessage(message_object);
    var object_cached = array_message[2];
    /*********************************************************************/
    
    
    
     
  6. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 485
    J'aime reçus:
    28
    Bonjour

    Voici l'algorithme, tel que je me le représente.

    Peut-être faudrait-il associer un identifiant à chaque message.

    Code:
    
         
                /*************************/
                /**        MAIN THREAD  **/----------------------------------------
                /*************************/                    |                  |
                    |        |            |                    |                  |
                  -----      |          -----                  |                  |
                  | 1 |      |          | 3 |                  |                  |
                  -----      |          -----                 /|\                 \|/
                    |        |            |                    |                  |
                    |        |            |                    |                  |
                ---------    |    -----------------            |                  |
                | READY |    |    |       READ    |            |                  |
                ---------    |    |    str_cache  |            |                  |
                    |        |    |  obj_message  |            |                  |
                    |        |    -----------------            |                  |
                    |        |            |                    |                  |
                   \|/       /|\         \|/                   |                  |
                    |        |            |            -----------------    -------------
                    |   -------------     |            |      WRITE    |    |      OK   |
                    |   |     READ   |    |            |    str_cache  |    | str_cache |
                    |   | str_cache  |    |            |  obj_message  |    -------------
                    |   -------------     |            -----------------          |
                    |        |            |                    |                  |
                    |      -----          |                  -----               \|/
                    |      | 2 |          |                  | 4 |                |
                    |      -----          |                  -----              -----
                    |        |            |                    |                | 5 |
                    |        |            |                   /|\               -----
                /*************************/                    |                  |
                /**      SERVICE WORKER **/------------------------<---------------
                /*************************/
    
    
    |/code]
     
    #6 ortolojf, 20 Août 2021
    Dernière édition: 20 Août 2021
  7. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 485
    J'aime reçus:
    28
    Le problème persiste.

    Impossible de conserver les valeurs de port1 et port2 entre chaque séquences WRITE ou bien READ.

    L'initiative de l'ouverture d'une connexion MessageChannel, vient toujours du main thread, jamais du service worker.

    Pourrait-on imaginer un système client-serveur, avec serveur dans le service worker, et client dans le main thread ou le service worker, avec connexion possible des clients vers le serveur, de manière à rendre possible les échanges WRITE, et READ ?

    Ce concept ( à comparer avec une connexion HTTP, nécessiterait théoriquement un port serveur prévisible, sinon constant.

    Théoriquement, une connexion MessageChannel, ne s'arrête qu'avec le close().

    Comment savoir à l'avance le port serveur, tout en disposant d'un port client correct ?

    Comment se connecter en MessageChannel, à un simili serveur ?

    Si le problème est simplement la synchronisation entre initialisation WRITE ( ou READ ), et réponse WRITE ( ou READ ), comment savoir à quel moment débuter la connexion du main thread vers le service worker ?

    Merci beaucoup de votre aide.

    Amicalement.
     
  8. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 485
    J'aime reçus:
    28
    Rebond

    Je joins les ports port1 et port2 de MessageChannel aux postMessage, mais je ne sais pas quel serait le séquencement des messages entre le main thread ( page HTML : window ), et le ServiceWorker( navigator.serviceWorker.controller ).

    Voici le code :

    Code:
    
    
    /*****************************************************************/
    /*                            MAIN THREAD                            **/
    /*****************************************************************/
    const isJson=function(item) {
            item = typeof item !== "string" ? JSON.stringify(item) : item;
            try {
                    item = JSON.parse(item);
            } catch (e) {
                    return false;
            }
            if (typeof item === "object" && item !== null) {
                    return true;
            }
            return false;
    }
    const Type=function(value) {
            if (typeof value === 'undefined') {
                    return 'undefined';
            }
            if(value === null) {
                    return 'null';
            }
            if(typeof value === 'object' &&
                    !Array.isArray(value)) {
                    return 'object';
            }
            if(isJson=(value) {
                    return 'Json';
            }
                    if( Array.isArray(value)) {
                            return 'array';
                    }
                    if(isNaN(value) {
                            return 'NaN';
                    }
                            if (typeof value === 'boolean') {
                                    return 'boolean';
                            }
                            if (typeof value === 'bigint') {
                                    return 'bigint';
                            }
                            if (typeof value === 'number') {
                                    return 'number';
                            }
                            if (typeof value === 'string' || value instanceof String) {
                                    return 'string';
                            }
                            if !isNaN(Date.parse(value)) {
                                    return 'date';
                            }
                            if (typeof value === 'symbol') {
                                    return 'symbol';
                            }
                            if (typeof value === 'function') {
                                    return 'function';
                            }
                            return 'object';
                    }
    Storage.prototype.setObject = function(key, value) {
            var tmp_type = Type(value);
            var tmp_array = ['object', 'array', 'Json', 'symbol'];
            if(tmp_array.indexOf(tmp_type) !== -1) {
                    try {
                            this.setItem(key, JSON.stringify(value));
                    } catch (e) {
                            return 'FALSE';
                    }
                    return 'TRUE';
            }
            if(tmp_type === 'function') {
                    return 'FALSE';
            }
            try {
                    this.setItem(key, value);
            } catch (e) {
                    return 'FALSE';
            }
            return 'TRUE';
    }
    Storage.prototype.getObject = function(key) {
            var value = this.getItem(key);
            var tmp_type = Type(value);
            var tmp_array = ['object', 'array', 'Json', 'symbol'];
            if(tmp_array.indexOf(tmp_type) !== -1) {
                    try {
                            result = value && JSON.parse(value);
                    } catch (e) {
                            return 'FALSE';
                    }
                    return result;
            }
            return value;
    }
    const wrapObjectMessage=function(ports, str_cache, message, object_message) {
            var array_message = ['READY', 'OK', 'READ', 'WRITE'];
            if(array_message.indexOf(message) == -1) {
                    return false;
            }
            return JSON.stringify({'ports': ports, 'cache': str_cache, 'type': message, 'object_cache': object_message});
    }
    const resObjectMessage=function(message) {
            JSON.parse(message);
            return [object_message.ports, object_message.str_cache, object_message.type, object_message.object_cache];
    }
    /*****************************************************/
    /**                  ALGORITHME DE CACHE                **/
    /*****************************************************/
    /**    1)    INITIALISATION    => READY                    **/
    /*****************************************************/
    /**    2) SERVICE WORKER    => ASK READ | WRITE CACHE    **/
    /*****************************************************/
    /**    3) MAIN THREAD        =>    SEND READ CACHE            **/
    /*****************************************************/
    const manageMessageFromWorker=function(message_object) {
            var log                = console.log.bind(console);
            var error            = console.error.bind(console);
            var    ports            = message_object.ports
            var std_cache        = message_object.str_cache;
            var type            = message_object.type;
            var object_message    = message_object.object_cache;
            if(['READY', 'OK', 'READ', 'WRITE'].indexOf(type) === -1) {
                    console.log('return type = ' + type);
                    return false;
            }
            /*****************************/
            /**    ENVOI => SERVICE WORKER    **/
            /*****************************/
            var    PORT1            = ports.port1;
            /*********************************/
            /**    RECEPTION <= SERVICE WORKER    **/
            /*********************************/
            var    PORT2            = ports.port2;
            var myStorage        = window.localStorage;
            var    message            = null;
            var response        = null;
            switch (type) {
                    case 'OK' :
                    case 'READY' :
                  
                            return true;
                            break;
                    case 'READ' :
                            /*********************/
                            /**    LECTURE CACHE    **/
                            /*********************/
                            object_message = myStorage.getObject(str_cache);
                            /*************************/
                            /**    RETOUR DE L'OBJET    **/
                            /**    AU SERVICE WORKER.    **/
                            /*************************/
                            message    = wrapObjectMessage(ports, str_cache, type, object_message);
                            try {
                                    PORT1.postMessage(message);
                            } catch (e) {
                                    return false;
                            }
                            return true;
                            break;
                    case 'WRITE' :
                            /*********************/
                            /**    ECRITURE CACHE    **/
                            /*********************/
                            if((response = myStorage.setObject(str_cache, object_message)) === 'FALSE') {
                                    return false;
                            }
                            /*************************/
                            /**        ACKNOWLEDGE        **/
                            /**      SERVICE WORKER    **/
                            /*************************/
                            message = wrapObjectMessage(ports, str_cache, type, response);
                            try {
                                    PORT1.postMessage(message);
                            } catch (e) {
                                    return false;
                            }
                            return true;
                            break;
                    default :
                            break;
            }
            return false;
    });
    const initialization=function() {
            /*************************/
            /**        INITALIZE        **/
            /**      SERVICE WORKER    **/
            /*************************/
            var    message = null;
            var messageChannel = new MessageChannel();
            var ports = {'port1': [messageChannel.port1], 'port2': [messageChannel.port2]};
            try {
                    message = wrapObjectMessage(ports, null, 'READY', null);
                    navigator.serviceWorker.controller.postMessage(message);
            } catch (e) {
                    return false;
            }
            return true;
    }
    window.addEventListener('message', function(event) {
            manageMessageFromWorker(event.data);
    });
    if ('serviceWorker' in navigator) {
            // Set up a listener for messages posted from the service worker.
            // The service worker is set to post a message to all its clients once it's run its activation
            // handler and taken control of the page, so you should see this message event fire once.
            // You can force it to fire again by visiting this page in an Incognito window.
            navigator.serviceWorker.addEventListener('message', function(event) {
            }
                    // Wait until the service worker is active.
                    navigator.serviceWorker.register('service-worker.js').then(function() {
                            return navigator.serviceWorker.ready;
                    }).then(function() {
                    }).catch(function(error) {
                            // Something went wrong during registration. The service-worker.js file
                            // might be unavailable or contain a syntax error.
                            console.log(error);
                    });
    } else {
            console.log('This browser does not support service workers.');
    }
    
    
    
     
  9. ortolojf
    ortolojf WRInaute accro
    Inscrit:
    14 Août 2002
    Messages:
    3 485
    J'aime reçus:
    28
    Rebonjour

    A propos des variables globales à l'intérieur d'un service worker :

    Après quel cycle du SW la variable disparaît ?

    Si je peux mettre les ports du MessageChannel en variable globale, ces ports seraient utilisables continûment durant les échanges avec la page thtml.

    Merci beaucoup de vos réponses.

    Respectueusement.
     
Chargement...
Similar Threads - Javascript API cache Forum Date
JavaScript et API Gmaps - Clusters de markers contenu dans une base de donnée Développement d'un site Web ou d'une appli mobile 15 Août 2015
Javascript et preloader Référencement Google 16 Septembre 2021
Comment lancer du Javascript sans html ? Développement d'un site Web ou d'une appli mobile 28 Avril 2021
Pop up javascript + cookie Développement d'un site Web ou d'une appli mobile 3 Février 2021
Du php dans du javascript Développement d'un site Web ou d'une appli mobile 16 Novembre 2020
Editer document Word avec Javascript Développement d'un site Web ou d'une appli mobile 10 Septembre 2020
Quelle extension Chrome pour expander les liens Javascript Développement d'un site Web ou d'une appli mobile 30 Août 2020
Javascript et duplication de Hn Problèmes de référencement spécifiques à vos sites 21 Août 2020
Quels Outils Javascript pour générer des documents Demandes d'avis et de conseils sur vos sites 21 Juillet 2020
HTML fait par Javascript <=>gérer les Events ? Développement d'un site Web ou d'une appli mobile 5 Juillet 2020