locked
WebView.InvokeScriptAsync not working in universal app

    Question

  • I am very new to javascript and webview so please bare with me.

    I am using a webview to display a certain html file, However, when I call InvokeScriptAsync, I keep encountering the error.
    "Unknown name. (Exception from HRESULT: 0x80020006 (DISP_E_UNKNOWNNAME))". This occurs eventhough the script is called in NavigationComplete or DOMContentLoaded.

    I prepared a simple app to debug this problem and I noticed that when the script is in a separate .js file, the error occurs.
    But if it is placed in the html file, the error would not occur.

    I am hoping to have the script in a separate file since I have a quite a lot of functions to implement and I would be using some third party scripts so it would not be maintainable having all the scripts on the html file.

    BTW, I did try the same code in a non-universal app and just used Windows 8.1 store app and it would work correctly even with the script stored in a separate file. That is why there must be some setting I am missing to make this work in a universal app.

    This is my MainPage code:

    public sealed partial class MainPage : Page
    {
    public MainPage()
    {
    this.InitializeComponent();
    MapWebView.NavigationCompleted +=MapWebView_NavigationCompleted;
    }
    
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
    Uri url = new Uri("ms-appx-web:///Common/Web/SamplePage.html");
    MapWebView.Navigate(url);
    }
    
    private async void MapWebView_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
    {
    try
    {
    await MapWebView.InvokeScriptAsync("SayHello", new string[] { "Hello! This is a test parameter" });
    }
    catch(Exception e)
    {
    string error = e.Message;
    }
    }
    }


    NOT WORKING (script is in a separate file which is sample.js):
    html file:

    <!DOCTYPE html>
    
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta charset="utf-8" />
    <title></title>
    </head>
    <body>
    <script type="text/javascript" src="sample.js"></script>
    <p>Parameter From Script File:</p> <div id="paramDiv"></div>
    </body>
    </html>


    sample.js file:

    function SayHello(parameter) {
    document.getElementById('paramDiv').innerHTML = parameter;
    }
    


    WORKING (script is in the html file):

    <!DOCTYPE html>
    
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta charset="utf-8" />
    <title></title>
    </head>
    <body>
    <script>
    function SayHello(parameter) {
    document.getElementById('paramDiv').innerHTML = parameter;
    }
    </script>
    <p>Parameter From Script File:</p> <div id="paramDiv"></div>
    </body>
    </html>

    Here is the setup of my project:
    I have my project setup as a universal app. In the shared code part of the universal app, I have the following files

    - Common (folder)
    - Web
    - SamplePage.html
    - sample.js

    Here is the link for the sample application: https://onedrive.live.com/?cid=b91cce8b55a904c8

    Thanks in advance!

    I have same post in stackoverflow btw.



    • Edited by gianime Tuesday, November 18, 2014 4:23 AM
    Tuesday, November 18, 2014 2:37 AM

Answers

  • After trying to figure this out the whole day i finally found that it is not even code related.

    It is a problem of Visual Studio generating the *.Shared.projitem file. This was the file before I edited it. The Javascript file was set to NONE. Unbelievable! I tried adding other javascript files and all of it were set to NONE for some strange reason.

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
        <HasSharedItems>true</HasSharedItems>
        <SharedGUID>d3aaa4f6-161b-4321-9b32-75aeb3d06444</SharedGUID>
      </PropertyGroup>
      <PropertyGroup Label="Configuration">
        <Import_RootNamespace>SampleWebViewUniversal</Import_RootNamespace>
      </PropertyGroup>
      <ItemGroup>
        <ApplicationDefinition Include="$(MSBuildThisFileDirectory)App.xaml">
          <SubType>Designer</SubType>
        </ApplicationDefinition>
        <Compile Include="$(MSBuildThisFileDirectory)App.xaml.cs">
          <DependentUpon>App.xaml</DependentUpon>
        </Compile>
        <Compile Include="$(MSBuildThisFileDirectory)MainPage.xaml.cs">
          <DependentUpon>MainPage.xaml</DependentUpon>
        </Compile>
      </ItemGroup>
      <ItemGroup>
        <Page Include="$(MSBuildThisFileDirectory)MainPage.xaml">
          <SubType>Designer</SubType>
          <Generator>MSBuild:Compile</Generator>
        </Page>
      </ItemGroup>
      <ItemGroup>
        <Content Include="$(MSBuildThisFileDirectory)Common\Web\SamplePage.html" />
      </ItemGroup>
      <ItemGroup>
        <None Include="$(MSBuildThisFileDirectory)Common\Web\sample.js" />
      </ItemGroup>
    </Project>

    To fix the problem, I manually changed it to Content and now, the script works as expected.

    I am very happy and hopefully this would help others as well.

     

    • Marked as answer by gianime Wednesday, November 19, 2014 2:30 AM
    Wednesday, November 19, 2014 2:21 AM

All replies

  • After trying to figure this out the whole day i finally found that it is not even code related.

    It is a problem of Visual Studio generating the *.Shared.projitem file. This was the file before I edited it. The Javascript file was set to NONE. Unbelievable! I tried adding other javascript files and all of it were set to NONE for some strange reason.

    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
      <PropertyGroup>
        <MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
        <HasSharedItems>true</HasSharedItems>
        <SharedGUID>d3aaa4f6-161b-4321-9b32-75aeb3d06444</SharedGUID>
      </PropertyGroup>
      <PropertyGroup Label="Configuration">
        <Import_RootNamespace>SampleWebViewUniversal</Import_RootNamespace>
      </PropertyGroup>
      <ItemGroup>
        <ApplicationDefinition Include="$(MSBuildThisFileDirectory)App.xaml">
          <SubType>Designer</SubType>
        </ApplicationDefinition>
        <Compile Include="$(MSBuildThisFileDirectory)App.xaml.cs">
          <DependentUpon>App.xaml</DependentUpon>
        </Compile>
        <Compile Include="$(MSBuildThisFileDirectory)MainPage.xaml.cs">
          <DependentUpon>MainPage.xaml</DependentUpon>
        </Compile>
      </ItemGroup>
      <ItemGroup>
        <Page Include="$(MSBuildThisFileDirectory)MainPage.xaml">
          <SubType>Designer</SubType>
          <Generator>MSBuild:Compile</Generator>
        </Page>
      </ItemGroup>
      <ItemGroup>
        <Content Include="$(MSBuildThisFileDirectory)Common\Web\SamplePage.html" />
      </ItemGroup>
      <ItemGroup>
        <None Include="$(MSBuildThisFileDirectory)Common\Web\sample.js" />
      </ItemGroup>
    </Project>

    To fix the problem, I manually changed it to Content and now, the script works as expected.

    I am very happy and hopefully this would help others as well.

     

    • Marked as answer by gianime Wednesday, November 19, 2014 2:30 AM
    Wednesday, November 19, 2014 2:21 AM
  • Hi gianime,

    I think that's expected, here you are reference a javascript in your local HTML page, but can you confirm you can successfully include all the javascript code into your HTML page? Probably you can't, because HTML page does not know where the file sample.js is

    If you modify the page as below(you already mentioned):

    <!DOCTYPE html>
    
    <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta charset="utf-8" />
        <title></title>
    </head>
    <body>
        <script type="text/javascript" src="sample.js"></script>
        <script>
            function btclick()
            {
    
            }
    
            function SayHello(parameter) {
                document.getElementById('paramDiv').innerHTML = parameter;
            }
        </script>
        <!--This works if script is in html file-->
        <!--<script>
        function SayHello(parameter) {
            document.getElementById('paramDiv').innerHTML = parameter;
        }
        </script>-->
    
        <p>Parameter From Script File:</p> <div id="paramDiv"></div>
        <button onclick="btclick()">Click me</button>
    </body>
    </html>

    The problem is HTML cannot load JS file because HTML page does not know where is sample.js.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.


    Wednesday, November 19, 2014 2:25 AM
    Moderator
  • Hi thanks for replying! 

    Yes it would work if I placed the script in the HTML page and that was my workaround as of yesterday. However, I just can't place all my script files in the html page since they are quite long and it would be hard to maintain.

    My problem was if I placed the script in a separate javascript file, it will not execute the script and would generate an UNKNOWN NAME error.

    Anyways, I did found out that it is a problem with Visual Studio not tagging javascript files correctly in the Shared.projitem that is why it cannot find the separate javascript file.

    BTW i am using Visual Studio 2013 Update 3. It could be a visual studio bug but for now, I am happy to just manually edit the .projitem file to make it work.

    Wednesday, November 19, 2014 2:40 AM
  • Nice to see the solution. It should help others.

    --James


    <THE CONTENT IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, WHETHER EXPRESS OR IMPLIED>
    Thanks
    MSDN Community Support

    Please remember to "Mark as Answer" the responses that resolved your issue. It is a common way to recognize those who have helped you, and makes it easier for other visitors to find the resolution later.

    Wednesday, November 19, 2014 5:49 AM
    Moderator