locked
ms-appx vs. ms-app and PostMessage

    Question

  • Hi,

    My app needs to display an iframe in one of the native app pages and the app need to use postMessage to communicate with the page in the iframe.

     

    So when I perform a "origin check" in the page of the iframe, what would be the appropriate URL to check in this case?

     

    I checked the e.origin is usually "ms-appx://hs003397-d840.....", is it true that every app will have a unique "ms-appx" url? Or every client will have a unique "ms-appx" url?

     

    I can also get a callback url for the application by calling:

    Windows.Security.Authentication.Web.WebAuthenticationBroker.getCurrentApplicationCallbackUri()

     

    This will return a "ms-app" url, which is my Secure Identification (SID). Can this somehow be used as a origin check component? 

    And.. what's the difference between "ms-app" url and "ms-appx" url?

    Thanks,


    Louis
    Wednesday, January 25, 2012 8:46 PM

Answers

  • No problem...we all have to learn these details at some point!

    For background on ms-wwa and ms-wwa-web (the current form in Developer Preview), see http://msdn.microsoft.com/en-us/library/windows/apps/hh452765.aspx. That has the brief usage. For full details, see the //Build session APP-476T (http://channel9.msdn.com/Events/BUILD/BUILD2011/APP-476T). 

    The short of it is that the two protocols indicate whether a page should run in the local context, which allows WinRT API access but not remote script and which sanitizes HTML added to the DOM (among other things), or the web context which allows remote script but no access to WinRT. Again, the //Build session has the details, but the web context is what you have to use when loading pages you don't control.

    Document.location.host in a Metro style app specifically returns the "package moniker" (a long string of gobbely-book--a hash of some of the id information in the manifest), which is akin to the local folder where the app is installed. When posting to an iframe, the key idea is that you're posting to the frame first, not the page within the frame, hence the use of ms-wwa-web:// + document.location.host. The iframe might then be doing some bridging itself (not sure on that).

    You would only be using postMessage to an iframe, by the way, when you know for sure that the hosted page can respond to such messages. This primarily works when you control that hosted page directly; when you don't, then it would have to have a documented API that you can use in this manner; otherwise you really don't know what will happen. On the flip side, a page you don't control probably wouldn't be arbitrarily posting messages back to its parent unless specifically doc'd as such or a page that you again write yourself. An example of the latter case is creating your own page to host a Bing Maps Ajax control, which has to be loaded through remote script (see http://alastaira.wordpress.com/2011/09/26/creating-a-windows-8-metro-slippy-map-application/ for an example).

    For your #3, if you want to check origin within the message event handler of an iframe page, or within a local context page, then you can just use the ms-wwa-web://  or ms-wwa:// + document.location.host, respectively. In the former case, this is how a page would distinguish between running in a browser vs. being run in an iframe in a Metro style app.  In the latter case, such a origin check might not be necessary, because your app should know what other pages its hosting can really can't receive messages from other sources anyway.

    Hope all that helps.

    Thursday, January 26, 2012 2:16 PM

All replies

  • The trick is to use document.location.host to get the package name, which you then prepend with ms-appx:// or ms-appx-web:// as needed (this is for more recent builds, which you clearly have; in the first Developer Preview these are ms-wwa:// and ms-wwa-web://). You don't need to use the Windows.Security stuff at all (nor be concerned with ms-app://).


    So to postMessage from your app to the iframe, use:


    frame.postMessage(message, "ms-appx-web://" + document.location.host); 
    


    The app can then use the same string as in the second parameter above to check the origin.


    From the iframe back to the app, use:

    window.parent.postMessage(message, "ms-appx://" + document.location.host);
    


    And then the app check the origin with the same string again.


    .Kraig
    Wednesday, January 25, 2012 11:49 PM
  • Hi Kraig,

     

    Thanks for your answer. I just have a few more questions. I need to mention that the page in the iframe is some pages like msdn.com or buildwindows.com, which is a real app url

     

    1. I am not very familiar with the usage of "ms-appx-web"/"ms-appx" or "ms-wwa-web"/"ms-wwa". Could you please provide a link that has related information or samples?

     

    2. I am not very familiar with the usage of document.location.host either. So I don't understand the usage of document.location.host here. When you try to post to msdn.com, the 2nd param of postMessage should be something like http://msdn.com, right? So, when you call frame.postMessage in App, wouldn't document.location.host give you your App package name instead of msdn.com?

     

    3. When you mention the same string to check, you mean hard coded the string, instead of retrieving it by document.location.host, right? 

     

    Thanks for your answer and I am really unfamiliar with all these, so please understand if I asked any stupid questions.

     

    Thanks


    Louis
    Thursday, January 26, 2012 2:24 AM
  • No problem...we all have to learn these details at some point!

    For background on ms-wwa and ms-wwa-web (the current form in Developer Preview), see http://msdn.microsoft.com/en-us/library/windows/apps/hh452765.aspx. That has the brief usage. For full details, see the //Build session APP-476T (http://channel9.msdn.com/Events/BUILD/BUILD2011/APP-476T). 

    The short of it is that the two protocols indicate whether a page should run in the local context, which allows WinRT API access but not remote script and which sanitizes HTML added to the DOM (among other things), or the web context which allows remote script but no access to WinRT. Again, the //Build session has the details, but the web context is what you have to use when loading pages you don't control.

    Document.location.host in a Metro style app specifically returns the "package moniker" (a long string of gobbely-book--a hash of some of the id information in the manifest), which is akin to the local folder where the app is installed. When posting to an iframe, the key idea is that you're posting to the frame first, not the page within the frame, hence the use of ms-wwa-web:// + document.location.host. The iframe might then be doing some bridging itself (not sure on that).

    You would only be using postMessage to an iframe, by the way, when you know for sure that the hosted page can respond to such messages. This primarily works when you control that hosted page directly; when you don't, then it would have to have a documented API that you can use in this manner; otherwise you really don't know what will happen. On the flip side, a page you don't control probably wouldn't be arbitrarily posting messages back to its parent unless specifically doc'd as such or a page that you again write yourself. An example of the latter case is creating your own page to host a Bing Maps Ajax control, which has to be loaded through remote script (see http://alastaira.wordpress.com/2011/09/26/creating-a-windows-8-metro-slippy-map-application/ for an example).

    For your #3, if you want to check origin within the message event handler of an iframe page, or within a local context page, then you can just use the ms-wwa-web://  or ms-wwa:// + document.location.host, respectively. In the former case, this is how a page would distinguish between running in a browser vs. being run in an iframe in a Metro style app.  In the latter case, such a origin check might not be necessary, because your app should know what other pages its hosting can really can't receive messages from other sources anyway.

    Hope all that helps.

    Thursday, January 26, 2012 2:16 PM
  • Ok. Kraig. Thanks for your answer. 

     I kind of understand it a bit more now.


    Louis
    Thursday, January 26, 2012 10:52 PM
  • Hi kraig,

    It was nice to listen your teched session in Bangalore.

    I have one issue with webcontext.

    In order to communicate an iframe we need to use webcontext (ms-appx-web:)and postmessage calls to send message from metro to iframe but when i use Pagenavigator control and I have fragment  in which iframe is present i am not able to sendmessage using postmessage html5 call to the iframe wven if i call 

     mapframe.postMessage(msgS, "ms-appx-web://" + document.location.host);

    Nothing happens. But if i have a single page and iframe it works. What piece is missing when we use pagenavigator control ? 

    Regards,

    Anuj

    • Edited by Anuj Sethi Tuesday, April 03, 2012 8:42 AM editted
    Tuesday, April 03, 2012 8:41 AM
  • Thanks--glad you enjoyed TechEd. It was a nice trip for me...and the shortest I've made to India (only 5 days).

    That's curious. I have the same kind of code working just fine within a page control. How are you obtaining the mapframe variable? I'm using document.frames["map"] where "map" is the id of my iframe. All of this is inside the ready function of the page control that's loaded with the PageControlNavigator.

    .Kraig

    Tuesday, April 10, 2012 3:32 PM