Azure移动服务javascript SDK在Firefox中不起作用

Azure Mobile Service javascript SDK does not work in Firefox

本文关键字:Firefox 不起作用 SDK 移动 服务 javascript Azure      更新时间:2023-09-26

我有一个用C#编写的简单Azure移动服务后端,它在/api/CustomLogin上具有登录功能。以下函数是我用Javascript为访问这些数据的web应用程序进行的简单登录测试:

var client = new WindowsAzure.MobileServiceClient(
    URL,
    API_KEY
);
function tryLogin(username, password) {
    client.invokeApi("CustomLogin", {
        body: {
            username: username,
            password: password
        },
        method: "post"
    }).done(function (results) {
        alert(JSON.stringify(results));
    }, function (err) {
        alert("Error: " + err);
    });
}

这在Chrome37和InternetExplorer11上运行良好,并返回具有正确状态代码和身份验证令牌的JSON对象。然而,当我在Firefox32上运行这个测试时,它会返回一个空对象{},这意味着我没有收到用户信息。我使用的Azure移动服务SDK来自http://ajax.aspnetcdn.com/ajax/mobileservices/MobileServices.Web-1.2.2.min.js.

我已经在本地主机和部署的网页(也托管在Azure网站上)上测试了这一点,使用了http和https(由Azure提供),这在Chrome和Internet Explorer上有效,但在Firefox中无效。

移动服务API的其他功能在Firefox中工作,例如

var peopleTable = client.getTable('people');
var query = peopleTable.read().done(function (results) {
    alert(JSON.stringify(results));
}, function (err) {
    alert("Error: " + err);
});

这让我怀疑invokeApi有问题,但我不明白为什么这个问题只发生在Firefox中。

这里的问题是,在.NET后端,默认情况下启用内容协商-客户端可以询问服务它"更喜欢"响应哪些内容类型(通过Accept标头)。在大多数浏览器中,客户端请求会说它"接受"所有内容,而.NET后端中使用的"首选"格式化程序是在网络上将对象转换为JSON的格式化程序。

然而,Firefox发送了一个Accept头,表示它更喜欢接收XML。后端将很高兴地响应,您的API调用将收到服务发送的XML响应。您甚至可以查看响应的responseText属性并在那里看到它。

function tryLogin(username, password) {
    client.invokeApi("CustomLogin", {
        body: {
            username: username,
            password: password
        },
        method: "post"
    }).done(function (response) {
        alert(response.responseText);
    }, function (err) {
        alert("Error: " + err);
    });
}

现在,如果您不想处理XML(我不会责怪您),您有两个选择:在服务器端,从服务器的格式化程序列表中删除XML格式化程序。在WebApiConfig上,这一行应该可以完成任务:

config.Formatters.Remove(config.Formatters.XmlFormatter);

或者,您可以覆盖firefox发送的Accept头,方法是在调用API时直接传递它:

function tryLogin(username, password) {
    client.invokeApi("CustomLogin", {
        body: {
            username: username,
            password: password
        },
        method: "post",
        headers: { Accept: 'application/json' }
    }).done(function (response) {
        alert(JSON.stringify(response.result));
    }, function (err) {
        alert("Error: " + err);
    });
}

一旦这样做,您将在成功回调的参数的result属性中获得API的结果。