Ajax标头基本身份验证:请求超时不适用于wp8

问题描述:

我目前正在为VLC Media Player编写遥控器.我使用http-webinterface连接到并控制服务器.从2.1.0版开始,VLC需要设置密码.这本身不是问题.我通过以下Ajax-Request解决了它

I am currently writing a remote for the VLC Media Player. I use the http-webinterface to connect to and control the server. Since version 2.1.0 VLC requires a password to be set. This itself is not a problem. I solved it with the following Ajax-Request

checkConnection = function(id, folder){
$.ajax({
    url: 'http://' + data.ip + ":" + data.port + '/requests/status.xml',
    headers: {
        "Authorization" : "Basic " + data.authorization
    },
    timeout: 3000,
    success: function (data, status, jqXHR) {
        //Yeah do stuff
        }       
    },
    error: function(data){
        //Ohh, do stuff
    }
  });
};

如果我使用计算机连接到VLC http界面,则会出现一个标准弹出窗口,要求我提供用户名和密码.我现在的问题是,如果data.authorization中的令牌错误,则该应用程序(使用电话)将崩溃.如果使用Ripple(使用Chrome)进行了测试,则会显示上述弹出窗口,但超时有效,并且我的错误处理开始.在Windows Phone上不是这种情况-这里我的应用程序挂起(如前所述).我确实怀疑,因为它是一个Webview,所以WP试图显示弹出窗口,但是失败了.再说一次,超时应该开始吗?

If I connect to the VLC http-interface using my computer there is this standard popup asking me for the username and a password. My problem right now is, that if the token in data.authorization is wrong, the app (using the phone) crashes. If tested with Ripple (using Chrome) the mentioned popup shows, but the timeout works and my error handling kicks in. This is not the case on my Windows Phone - here my app hangs (as mentioned). I do suspect, that since it is a webview WP tries to display the popup, but fails. Then again, the timeout should kick in?

你们中有人有同样的问题吗?如果是的话,您是如何解决的?

Did any of you have the same problem and if so how did you solve it?

最终解决.这很容易,只需要用C#编写一个插件即可.我将为可能遇到相同问题的任何人附加代码.

Finally solved. It was quite easy and just required writing a plugin in C#. I'll attached the code for anybody who might encounter the same problem.

using System;
using System.IO;
using System.Net;
using System.Runtime.Serialization;
using System.Text;
using System.Windows.Threading;
using WPCordovaClassLib.Cordova;

namespace WPCordovaClassLib.Cordova.Commands
{
    public class BasicAuth : BaseCommand
    {
        //Create timer to control timeout
        DispatcherTimer timeoutTimer = new DispatcherTimer();
        WebClient webClient = new WebClient();

    public BasicAuth(){
        timeoutTimer.Interval = TimeSpan.FromSeconds(5);
        timeoutTimer.Tick += new EventHandler(timeout);
        timeoutTimer.Start();
    }

    public void get(string options)
    {
        //Parse data that gets passed into the plugin
        string[] passedData = JSON.JsonHelper.Deserialize<string[]>(options);

        string ip = passedData[0];
        string port = passedData[1];
        string username = passedData[2];
        string password = passedData[3];            

        try
        {
            webClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(webClient_DownloadStringCompleted);
            string credentials = String.Format("{0}:{1}", username, password);
            byte[] bytes = Encoding.UTF8.GetBytes(credentials);
            string base64 = Convert.ToBase64String(bytes);
            string authorization = String.Concat("Basic ", base64);
            webClient.Headers["Authorization"] = authorization;
            string url = //your url here
            var uri = new Uri(url);
            webClient.DownloadStringAsync(uri);
        }
        catch (Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Data);
            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ""));
            timeoutTimer.Stop();
        }
    }

    void webClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
    {
        try{
            DispatchCommandResult(new PluginResult(PluginResult.Status.OK, e.Result)); //e.Result will fail if the server couldn't be contacted
        } catch{
            DispatchCommandResult(new PluginResult(PluginResult.Status.ERROR, ""));
        }
    }

    private void timeout(Object sender, EventArgs e)
    {
        webClient.CancelAsync(); //Cancel Async download
        timeoutTimer.Stop(); //Stop timer from beeing executed again
    }
}
}

以下是您可以通过JavaScript调用的地方:

Here is the bit you would call from your JavaScript:

cordova.exec(connectionSuccess, connectionError, "BasicAuth", "get", [data]);