【问题标题】:Getting XMLHttpRequest to work on Windows Phone HTML5 App让 XMLHttpRequest 在 Windows Phone HTML5 应用程序上工作
【发布时间】:2026-02-21 15:10:01
【问题描述】:

在 Microsoft Visual Studio Express 中,我使用“Windows Phone HTML5 App”模板启动了一个新项目。如果我运行模拟器,一切正常。接下来我将以下 JavaScript 添加到 index.html 页面:

<script type="text/javascript">
   window.onload = function(){

      alert(window.location.href); // -->  x-wmapp0:/Html/index.html

      var xmlhttp = new XMLHttpRequest();
      xmlhttp.onreadystatechange=function()
      {
         alert('ON READY STATE CHANGE');
         if(xmlhttp.readyState==4){
            alert(xmlhttp.responseText);
          }
       }

       //xmlhttp.open("GET","text.txt",true); // I have tried all of these
       //xmlhttp.open("GET","Html/text.txt",true);
       //xmlhttp.open("GET","/Html/text.txt",true);

       xmlhttp.open("GET","x-wmapp0:/Html/text.txt",true);
       xmlhttp.send();
   }

</script> 

现在,当我在模拟器中运行应用程序时,我会收到第一个带有窗口位置的警报,但不会收到来自 readyStateonreadystatechange 的任何警报。 text.txt 文件与 index.html 处于同一级别。我已经在 IE10 中运行了这段代码,它工作得很好。关于我做错了什么有什么想法吗?

更新:我已经将它部署在实际的 Windows 8 手机上并得到了相同的结果

干杯

【问题讨论】:

  • 你检查xmlhttp.status == 200了吗?
  • 是的,您可以检查任何状态,onreadystatechange 函数似乎根本没有触发。
  • 您的实时代码中有alert() 吗? IE 有时会出于某种原因拒绝正确运行任何使用alert() 的代码。
  • 我已取出警报,但仍然没有成功
  • 您确定您在open() 方法中的路径是正确的吗?您必须在手机上安装该主机才能正常工作。

标签: javascript html visual-studio xmlhttprequest windows-phone


【解决方案1】:

这是微软从MSDN 告诉我的内容

XMLHttpRequest 仅适用于检索网络资源。即,您不能使用它来访问应用程序本地存储(即 XAP 或独立存储)中的内容。

这是我过去用来解决此限制的脚本 + 代码示例:

带有 JavaScript 的 HTML 页面:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"> 
<head> 
  <title>test</title> 
  <script type="text/javascript">

      function LoadFile(SourceURL) {
          try {
              var httpfreq = new XMLHttpRequest();
              httpfreq.onreadystatechange = function () {
                  filecontent.innerText = "httpfreq.onreadystatechange fired, readyState = " + httpfreq.readyState.toString();
                  if (httpfreq.readyState = 4) {
                      filecontent.innerText = "Status = " + httpfreq.status.toString();
                      if (httpfreq.status = 200) {
                          window.external.notify("Received content" + httpfreq.responseText);
                          filecontent.innerHTML = httpfreq.responseText;
                      }
                      else {
                          window.external.notify("Error loading page: " + SourceURL);
                          filecontent.innerText = "Error loading page " + SourceURL;
                      }
                  }
              };

              httpfreq.open("GET", SourceURL);
              httpfreq.send(null);

          }
          catch (e) {
              if (e.number = 0x80070005) {
                  LoadLocalFile(SourceURL, "GetResourceCallback");
              }
              else {
                  alert(e.name + " " + e.number.toString());
              }
          }
      }

      function LoadLocalFile(SourceURL, callbackfn) {
          window.external.notify("GetResource?file=" + SourceURL + ";callback=" + callbackfn);
      }

      function GetResourceCallback(StringContent) {
          filecontent.innerText = StringContent;
      }


  </script> 
</head> 
<body> 
<p> 
test page: notes.html
</p> 
    <p><input type="button" onclick="LoadFile('text.txt')" value="Load Local" /> </p>
    <p><input type="button" onclick="LoadFile('http://www.somedomain.com/text.txt')" value="Load remote" /> </p>
    <p>---------------------------</p>
    <div id="filecontent"></div>
    <p>---------------------------</p>
</body> 
</html>

以及所需的App Host代码(c#)

private void webBrowser1_ScriptNotify(object sender, NotifyEventArgs e)
    {
        System.Diagnostics.Debug.WriteLine("Script Notify : {0}",e.Value);

        if (e.Value.Contains("GetResource?file="))
        {
            Dispatcher.BeginInvoke(() =>
                {
                    String szArgs = e.Value;

                    string szResource = null;
                    string szCallbackFn = null;
                    char[] separators = new char[2] {'?',';'};
                    string[] parms = szArgs.Split(separators);

                    for (int i = 1; i < parms.Length; i++ )
                    {
                        if (parms[i].Contains("file="))
                        {
                            szResource = parms[i].Substring(5);
                        }
                        else if (parms[i].Contains("callback="))
                        {
                            szCallbackFn = parms[i].Substring(9);
                        }
                    }

                    if (!String.IsNullOrWhiteSpace(szResource) && !String.IsNullOrWhiteSpace(szCallbackFn))
                    {
                        // read local resource.
                        string szFileContent= "Resource not found!";
                        try
                        {
                            if (String.IsNullOrEmpty(webBrowser1.Base))
                            {
                                // if Base is not set then assume XAP file content.
                                szFileContent = ReadXAPResource(szResource);
                            }
                            else
                            {
                                // else assume IsolatedStorage
                                szFileContent = ReadISOFile(webBrowser1.Base, szResource);
                            }
                        }
                        catch (Exception)
                        {}

                        webBrowser1.InvokeScript(szCallbackFn, szFileContent);
                    }
                });
        }
    }

    private string ReadXAPResource(string szFile)
    {
        string szContent = "File Not Found";
        try
        {
            // in my project HTML files are in the HelpContent folder...
            StringBuilder szPath = new StringBuilder("HelpContent");
            if (!szFile.StartsWith("/"))
                szPath.Append("/");

            szPath.Append(szFile);

            StreamResourceInfo sri = Application.GetResourceStream(new Uri(szPath.ToString(), UriKind.Relative));

            if (null != sri)
            {
                StreamReader strm = new StreamReader(sri.Stream);
                szContent = strm.ReadToEnd();
            }
        }
        catch (Exception) { }

        return szContent;
    }

    private string ReadISOFile(string szBase, string szFile)
    {
        string szContent = "File Not Found";
        try
        {
            string fullPath = szBase + szFile;
            IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForApplication();
            IsolatedStorageFileStream isfsInput = isf.OpenFile(fullPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);

            if (null != isfsInput)
            {
                StreamReader strm = new StreamReader(isfsInput);
                szContent = strm.ReadToEnd();
            }
        }
        catch (Exception) { }

        return szContent;
    }

【讨论】:

  • 谢谢,这是金子!
  • 仅供参考e.number = 0x80070005 缺少=,对我来说是-2147024891(注意减号)
  • GetResourceStream 中请求的uri 也不能以/ 开头,我花了一段时间才找到。
  • @eivers88 您如何将字节数组传递给 javascript?我尝试使用字节数组调用 InvokeScript,但它只接受有意义的脚本,但我试图弄清楚如何将其与 pdf.js 一起使用,因为在 wp8.1 中使用时 XMLHttpRequest 似乎无法使用它
最近更新 更多