none
Le compartiment local versus le compartiment Web dans une application de style Metro qui utilise JavaScript RRS feed

Toutes les réponses

  • Le code JavaScript d’une page Web peut par default accéder à Windows APIs. Cela est évidement un risque de point de vue de sécurité si vous utilisez du code JavaScript téléchargé de l’Internet. Ce risque est atténué par partitionner la page web en deux compartiments logiques : local et web.

    L’application est exécutée dans le compartiment local et le code exécuté dans ce compartiment a accès à Windows APIs et peut faire des demandes http cross-domain (important si vous voulez obtenir data à l’aide de l’Internet). Le code externe est exécuté dans le compartiment web, via les éléments iframe.

    On va continuer développer l’application en ajoutant un control pour utiliser une carte dans notre application. Le control carte sera inclus dans la page HTML map.html. Dans Solution Explorer sélectez Add/New Item après un clic droit sur le dossier html :


    Visual Studio 11 Add new item

    Dans la boite de dialogue « Add New Item » sélectez “HTML page” et utilisez map.html pour le nom du fichier:

    Visual Studio 11 Add new item dialog


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.


    jeudi 1 mars 2012 13:40
  • Remplacez le contenu de map.htmlavec:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <title>Map</title>
            <script type="text/javascript" src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=7.0"></script>
            <script src="/winjs/js/base.js"></script>
            <script type="text/javascript" src="../js/map.js"></script>
        </head>
        <body>
            <div class="map" /> 
        </body>
    </html>
    


    Le code pour le control Bing Maps est charge à partir du web ce qui signifie qu’on va avoir toujours la dernière version de ce control dans notre application.

     



    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    jeudi 1 mars 2012 13:46
  •  

    En plus, la page va charger aussi le fichier ../js/map.js qu’on va définir dans les étapes suivants : via un clic droit sur le dossier js en Solution Explorer créez le fichier map.js et ajoutez le code suivant dans ce fichier:

    (function () {
        'use strict';
        var map = null;
        var mapCredentials = "AtdEdzGw6hwYDfHOU_un_NIssCc1gdEdBy3bXpmnAFqoNkszL83o6qTeLM04j3b0";
        var homeLoc = null;
        var homePushpin = null;
        function getMap() {
            var mapOptions = {
                credentials: mapCredentials
            }
            var s = document.querySelector(".map");
            map = new Microsoft.Maps.Map(s, mapOptions);
        }
        function listenForMessages() {
            window.addEventListener("message", onGetMessage, false);
        }
        function parseResponse(responseText) {
            var responseObj = JSON.parse(responseText);
            return responseObj;
        }
        function setHomeLoc(loc) {
            var lat = parseFloat(loc.Latitude);
            var longitude = parseFloat(loc.Longitude);
            homeLoc = new Microsoft.Maps.Location(lat, longitude);
            if (!homePushpin) {
                homePushpin = new Microsoft.Maps.Pushpin(homeLoc, { draggable: false });
                map.entities.push(homePushpin);
            }
            else {
                homePushpin.setLocation(homeLoc);
            }
        }
        function recenter(currentLoc) {
            var lat = parseFloat(currentLoc.Latitude);
            var longitude = parseFloat(currentLoc.Longitude);
            map.setView({ center: new Microsoft.Maps.Location(lat, longitude) });
        }
        function setZoom(num) {
            map.setView({ zoom: num });
        }
        function onGetMessage(e) {
        // TODO: implement this
        }
        window.onload = function () {
            listenForMessages();
            getMap();
        }
        WinJS.Namespace.define("Map", {
            getMap: getMap,
            listenForMessages: listenForMessages,
            parseResponse: parseResponse,
            setHomeLoc: setHomeLoc,
            recenter: recenter,
            setZoom: setZoom,
            onGetMessage: onGetMessage,
            });
        })();


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    jeudi 1 mars 2012 13:47
  • Notez que ce code crée un objet Microsoft.Maps.Maplié à l’élément map défini dans map.html.Puis on a lié une fonction à l’évènement window.onloadà la fin du code JavaScript. Cette liaison représente l’initialisation de la page quand map.html est charge pour la première fois.

     

    Pour le code qui va charger map.htmldans le compartiment web on va utiliser un élément iframepour charger et pointer cers le contenu HTML (localisé dans le package de l’application) en utilisant un URL qui commence avec ms-wwa-web://. Ouvrez detailPage.htmlet remplacez le div avec l’attribut classégal a mapControlavec:

    <iframe class="mapControl" src="ms-wwa-web:///html/map.html"></iframe>

     

     

    L’URL ms-wwa-web indique que la page référencée doit être chargée dans le compartiment web.

     

    Finalement, le conteneur de l’application doit savoir qu’on veut utiliser l’internet. Cela se fait par cocher Internet dans l’onglet « Capabilities » de notre manifeste :

     Metro style manifest capabilities

    Si toutes les étapes ont été respectées et vous exécutez l’application, vous allez voir:


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.


    jeudi 1 mars 2012 13:51
  • Maintenant on va écrire du code pour envoyer data entre les deux compartiments de notre application. Vu que le compartiment local n’est pas limité pour obtenir data de différents domaines, la plupart du temps les informations dont l’utilisateur a besoin se trouvent dans ce compartiment. Donc, si on veut utiliser un service web comme Bing Maps, il faut envoyer les données  au compartiment web et on peut le faire en utilisant les APIs postMessage.

     

    On commence par écrire du code qui envoie un message au control Bing Maps.  Dans le fichier detailPage.js ajoutez les lignes de code suivantes à la fonction fragmentLoad :

    var photoLoc = { Latitude: 52.06152124180943, Longitude: 4.20710988342762 };
    postMessage(".mapControl", "PhotoLocation", photoLoc);
    
    pour passer le message “PhotoLocation” a l’élément mapControl et obtenir:
    
        function fragmentLoad(elements, options) {
            elements.querySelector('.pageTitle').textContent = "North Sea Sunset";
            WinJS.UI.processAll(elements)
                .then(function () {
                var detailsToInject = ["<p>North Sea Beach</p>",
                                            "<p>Location: The Hague, The Netherlands</p>",
                                            "<p>Details: Sunset over the North Sea</p>",
                                            "<p>Date Taken: 6/19/2011</p>"].join("");
                elements.querySelector('.imageDetails').innerHTML = detailsToInject;
                var detailsImage = elements.querySelector(".photoImage");
                detailsImage.innerHTML = '<img class="photoImage" src="../images/North Sea beach.png" alt="Sunset" height="' + detailsImage.clientHeight + '"/>';
    
                var photoLoc = { Latitude: 52.06152124180943, Longitude: 4.20710988342762 };
                postMessage(".mapControl", "PhotoLocation", photoLoc);
            }
        }
    

    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    jeudi 1 mars 2012 13:58
  • Pour pouvoir utiliser ce code, dans le fichier detailPage.js il faut définir aussi la fonction postMessage qui va recevoir le nom de l’iframe, le nom du message et les coordonnées comme paramètres :

    function postMessage(targetElemId, messageType, objToSend){
        var elem = document.querySelector(targetElemId);
        objToSend.messageType = messageType;
        elem.contentWindow.postMessage(JSON.stringify(objToSend), "*");
    }

    Cette fonction invoque la fonction postMessage de l’iframe pour l’objet avec les coordonnées transformé en string JSON.

    Dans le fichier map.js on va définir le code pour gérer l’objet reçu dans le compartiment web. Remplacez le contenu de la fonction onGetMessage avec le code suivant:

    var responseObj = parseResponse(e.data);
    if (responseObj.messageType == "PhotoLocation") {
        setHomeLoc(responseObj);
        recenter(responseObj);
        setZoom(8);
    }

    La fonction parseResponse invoque une routine JSON pour transformer le string dans un objet qui permet récupérer les coordonnées.


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    jeudi 1 mars 2012 14:06
  •  

    Si vous exécutez l’application vous constaterez que l’interface n’est pas mise à jour à la location correcte et vous êtes sur la vue générale de la carte. On va déboguer l’application, mais vu que les points d’arrêt modifient un peu les évènements on va utiliser le traçage. Le message est reçu dans onGetMessage de map.js, mais il est envoyé dans postMessage de detailPage.js. Ajoutez dans les deux méthodes la ligne suivante pour écrire des messages dans la console quand elles sont appelées :

    function onGetMessage(e) {
            console.log("in onGetMessage");
            var responseObj = parseResponse(e.data);

    et

    function postMessage(targetElemId, messageType, objToSend) {
            console.log("in postMessage");
            var elem = document.querySelector(targetElemId);

    Si vous exécutez l’application en mode débogage et cliquez sur une image vous allez voir dans la console JavaScript:
    Visual Studio 11 JavaScript console


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    jeudi 1 mars 2012 14:10
  • Donc le message est envoyé, mais pas reçu. On ajoute aussi une ligne dans la fonction  listenForMessages de map.js pour s’assurer qu’on est abonné à l’évènement “message”.

    function listenForMessages() {
            console.log("listenForMessages");
            window.addEventListener("message", onGetMessage, false);
        }

    Cette fois on obtient la séquence:

    Visual Studio 11 JavaScript Console


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    jeudi 1 mars 2012 14:12
  • Ça veut dire qu’on envoie le message avant commencer écouter, donc le message arrive avant pouvoir le gérer et on a besoin d’un délai avant envoyer le message pour attendre avoir toute la page chargée. Modifiez l’appel à postMessage en fragmentLoad et ajoutez un event listener pour savoir quand la page a été complètement chargée :

    //we need to wait for the IFrame to load
                elements.querySelector(".mapControl").addEventListener("load", function () {
                        postMessage(".mapControl", "PhotoLocation", photoLoc);
                    }, false);
                });

    Eliminez les messages écrites dans la console JavaScript et testez l’application:


    Suivez MSDN sur Twitter   Suivez MSDN sur Facebook


    Ciprian DUDUIALA, MSFT  
    •Nous vous prions de considérer que dans le cadre de ce forum on n’offre pas de support technique et aucune garantie de la part de Microsoft ne peut être offerte.

    jeudi 1 mars 2012 14:20