locked
Using JavaScript with Web Browser control RRS feed

  • Question

  • Hi,

    I built an application with MFC's CHtmlView (WebBrowser control) which depends on JavaScript. However, I found out that my application becomes unusable when the user has disabled JavaScript in the security settings.

    Is there a way to enable JavaScript in my application so that I can be sure that my application is useable??

    Thanks,

    Peter

     

    PS: I also implemented a small Asynchronous Protocol Handler myprotocol:// for this purpose. Maybe I can also set these settings within this implementation?

     

    Sunday, May 23, 2010 4:53 PM

Answers

  • Yes, you need to override the ole client site creation in CHTMLView to replace the default control site with your own site that implements the security manager interface (pretty much like how CHTMLView replaces the default site with one that implements IDocHostUIHandler).

    Since you have control over what is displayed in CHTMLView, so your content can be assumed safe for scripting. I suggest you to map all urls to a zone created by yourself so your software is not impacted by the user's security zone settings. 



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
    • Proposed as answer by Yi Feng Li Friday, May 28, 2010 2:40 AM
    • Marked as answer by Yi Feng Li Tuesday, June 1, 2010 2:06 AM
    Tuesday, May 25, 2010 12:05 AM
  • Hi,

     

    Thank you. Huh, really complicated :-(

    In the meantime I found another solution (but I am not sure)...

     

    The good thing: All content I display is called using my own Asynchronous Pluggable Protocol, e.g. myapp://...

     

    In the implementation of the pluggable protocol I added the following ParseUrl:

     

    STDMETHODIMP CMyPluggableProtocol::ParseUrl(LPCWSTR pwzUrl, PARSEACTION parseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
    {
      CString pch;
      switch(parseAction)
      {
        case PARSE_SECURITY_URL:
          pch = pwzUrl;
          if(pch.GetLength() <= 12)
            return INET_E_DEFAULT_ACTION;

          pch.Replace(_T("//"), _T("/"));
          pch.Replace(_T(":"), _T(""));
          pch.Insert(0, _T("file:///C:/"));

          if(cchResult <= static_cast<DWORD>(pch.GetLength()))
          {
            *pcchResult = static_cast<DWORD>(pch.GetLength() + 2);
            return S_FALSE;
          }

          swprintf(pwzResult, pch);
          *pcchResult = static_cast<DWORD>(wcslen(pwzResult) + 2);

          return S_OK;
      }

      return INET_E_DEFAULT_ACTION;
    }

    What happens is now that every link from my protocol is now file://c:/foo/bar/... and as such treated as local.

     

    I tried it: For all zones I set "high" and disabled all scripting stuff. --> My application works though :)

    Can you acknowledge that this is another good solution :-)

     

    Thank you,
    Peter

     

    • Marked as answer by Yi Feng Li Tuesday, June 1, 2010 2:07 AM
    Tuesday, May 25, 2010 2:00 PM

All replies

  • Is there a way to enable JavaScript in my application so that I can be sure that my application is useable??

    That would be a big security hole if your application could enable JavaScript when the user has explicitly turned it off.

    What your application should do is to detect if Javascript is turned on or not. If not, politely ask the user to turn it on, or to have the target URL placed in the Trusted Sites Zone, where presumably Javascript is enabled.

    Sunday, May 23, 2010 6:30 PM
  • NO!!!!! IT IS NOT!

     

    Please remember that the user executes a complete application on his client. If I want to make something bad there are much easier ways to do. Even worse, the application is installed as administrator.

     

    And: I only use the control to display HTML (as most of the people using the control as I guess). The control never receives any content from the web, it even can't do so!

    I only want to get the application working!

     

    In the meantime I found the usual and complex method: IInternetSecurityManager. But I have no experiences with COM. Can I add a COM class with VC.NET 2003 directly to an MFC project? Without registering anything?

     

    How do I attach my object to the CHtmlView?

     

    There is no information on the web :-( :-(

    Regards,

    Peter

     

    PS: Not even in the "local zone" JavaScript is enabled for sure. My app depends on JavaScript the same way as it depends on MFC, WebBrowser Control etc. So I need to get it work. And no, the user should not even need to know that the (proprietary, local application-)content is being displayed with HTML.

     

    Sunday, May 23, 2010 9:04 PM
  • Yes, you need to override the ole client site creation in CHTMLView to replace the default control site with your own site that implements the security manager interface (pretty much like how CHTMLView replaces the default site with one that implements IDocHostUIHandler).

    Since you have control over what is displayed in CHTMLView, so your content can be assumed safe for scripting. I suggest you to map all urls to a zone created by yourself so your software is not impacted by the user's security zone settings. 



    The following is signature, not part of post
    Please mark the post answered your question as the answer, and mark other helpful posts as helpful.
    Visual C++ MVP
    • Proposed as answer by Yi Feng Li Friday, May 28, 2010 2:40 AM
    • Marked as answer by Yi Feng Li Tuesday, June 1, 2010 2:06 AM
    Tuesday, May 25, 2010 12:05 AM
  • Hi,

     

    Thank you. Huh, really complicated :-(

    In the meantime I found another solution (but I am not sure)...

     

    The good thing: All content I display is called using my own Asynchronous Pluggable Protocol, e.g. myapp://...

     

    In the implementation of the pluggable protocol I added the following ParseUrl:

     

    STDMETHODIMP CMyPluggableProtocol::ParseUrl(LPCWSTR pwzUrl, PARSEACTION parseAction, DWORD dwParseFlags, LPWSTR pwzResult, DWORD cchResult, DWORD *pcchResult, DWORD dwReserved)
    {
      CString pch;
      switch(parseAction)
      {
        case PARSE_SECURITY_URL:
          pch = pwzUrl;
          if(pch.GetLength() <= 12)
            return INET_E_DEFAULT_ACTION;

          pch.Replace(_T("//"), _T("/"));
          pch.Replace(_T(":"), _T(""));
          pch.Insert(0, _T("file:///C:/"));

          if(cchResult <= static_cast<DWORD>(pch.GetLength()))
          {
            *pcchResult = static_cast<DWORD>(pch.GetLength() + 2);
            return S_FALSE;
          }

          swprintf(pwzResult, pch);
          *pcchResult = static_cast<DWORD>(wcslen(pwzResult) + 2);

          return S_OK;
      }

      return INET_E_DEFAULT_ACTION;
    }

    What happens is now that every link from my protocol is now file://c:/foo/bar/... and as such treated as local.

     

    I tried it: For all zones I set "high" and disabled all scripting stuff. --> My application works though :)

    Can you acknowledge that this is another good solution :-)

     

    Thank you,
    Peter

     

    • Marked as answer by Yi Feng Li Tuesday, June 1, 2010 2:07 AM
    Tuesday, May 25, 2010 2:00 PM