【问题标题】:Why can't I return $.ajax result but can return $http.post result?为什么我不能返回 $.ajax 结果但可以返回 $http.post 结果?
【发布时间】:2016-07-03 11:21:07
【问题描述】:

我有 2 个返回语句:

return $http.post({ 
    url: CHEAPWATCHER.config.domain + 'api/Authenticate',
    contentType: 'application/x-www-form-urlencoded; charset=UTF-8',
    data: data
});

return $.ajax({
    type: 'POST',
    url: CHEAPWATCHER.config.domain + 'api/Authenticate',
    data: data
}).done(function (result) {
    console.log('logged successfuly');
}).fail(function (result) {
    console.log('loging failed');
});

还有我使用 API 方法的 background.js 函数:

// REGISTER API COMMAND LISTENER
chrome.runtime.onConnect.addListener(function (port) {
    port.onMessage.addListener(function (request, portInfo) {
        // Globally accessible function to execure API calls
        CHEAPWATCHER.executeApiCall = function (request, senderId) {
            var originalRequestMethod = request.method;
            //Dinamically call API method
            CHEAPWATCHER.api[request.method](request, senderId).then(function (response) {
                port.postMessage(response);
            }, function (error) {
                port.postMessage(error);
            });
        };
        CHEAPWATCHER.executeApiCall(request, request.sender);
    });
});

当然,当我运行我的 chrome 扩展程序时,我会评论其中一个,但关键是它们都返回相同的对象类型 jqXHR,如果我使用的是 $http.post,它会给我以下错误:

事件处理程序中的错误(未知):TypeError:无法读取 null 的属性“错误”

和

POST chrome-extension://cmakfpdagfeiefcmmpmhjrtyhonmgnbi/background/[object%20Object] net::ERR_FILE_NOT_FOUND

当我使用 $.ajax 时,它可以工作,我得到了我需要的令牌,但它给了我这个错误:

事件处理程序中的错误(未知):TypeError:无法读取 null 的属性“错误”

之后我的扩展程序无法继续工作。昨天我问为什么 $.ajax 给了我这个错误,我得到了答案,因为我不能返回 jqXHR 类型,但是如果我使用的是

return $http.post(CHEAPWATCHER.config.domain + 'api/Authenticate', data);

一切都很好,只是 post 方法需要我给他 grant_type=password 和 Content-Type application/x-www-form-urlencoded 所以这就是我使用 $http.post([settings]) 结构的原因。

谁能解释一下它们是如何工作的以及为什么我会收到这些错误?也许我使用的 post 方法不正确,或者我需要声明更多我不知道的东西?

【问题讨论】:

  • @Barmar 抱歉忘了提到我正在使用 Angular。所以 $http 服务是一个核心 Angular 服务,它通过浏览器的 XMLHttpRequest 对象或 JSONP 促进与远程 HTTP 服务器的通信。
  • 您使用的是哪个版本的 jQuery?
  • @AhsanAyaz jQuery 2.2.1 版本
  • 这些响应(承诺)返回到哪里? “Cannot read property 'error' of null”表明,在某些时候,someObject.error 被引用。
  • “chrome-extension://cmakfpdagfeiefcmmpmhjrtyhonmgnbi/background/[object%20Object] ”似乎非常可疑,因为它看起来像是一个对象试图添加到一个字符串(给定 [object Object]序列化)-尽管这与您遇到的问题不太相关。

标签: javascript jquery angularjs ajax google-chrome


【解决方案1】:

您没有正确使用$http.post。此方法需要 3 个参数,而不是像这样的一个对象:

return $http.post(
   CHEAPWATCHER.config.domain + 'api/Authenticate',
   transformDataToUrlEncoded(data),
   {contentType: 'application/x-www-form-urlencoded; charset=UTF-8'}
});

如您所见,我放置了一个 transformDataToUrlEncoded。因为 Angular 只在 JSON 中序列化,所以他不会主动将 javascript 对象转换为 urlencoded。


来自超出主题的旧答案

$http.post 返回一个可以使用 .then 的承诺。 Angular promise 是可更改的,这意味着您可以一次又一次地执行 .then().then().then() 以对结果进行多层处理。当然你不需要那么频繁。我会说几乎永远不会超过 2 级:

  1. 在服务层处理来自服务器的结果并格式化数据
  2. 在控制器层中使用结果

我不太了解 JQuery,但我想那是它不能像 Angular 那样链接。

你应该可以的

.done().fail()

因为 .done 返回可以执行 .fail() 但不能执行的对象

.done().done(). 

因为 .done 返回的对象没有 .done() 方法。

最后 .fail() 是终止点:它什么也不返回,所以你返回空值。


【讨论】:

  • 在api.jquery.com/jquery.post/#jQuery-post-settings 中说 $http.post 的格式如下所示:jQuery.post( [settings ] ) 和设置是 plainObject 所以你可以使用 1 plainObject 参数@Walfrat跨度>
  • jQuery 承诺也是可链接的。正如我从@NikasŽalias 问题中了解到的那样,角度和jQuery 实现都会发生“TypeError:无法读取null 的属性'错误'”。我怀疑这正在发生,这可能有助于弄清楚代码在抛出此错误之前有多远。
  • 另外,很好地解决了 $http.post 使用问题@Walfrat——这可能是导致 Angular 版本中带有 [object Object] 的奇怪帖子 url 的原因
  • 正如@Walfrat 所说,我将 $http.post 语法更改为他建议的语法。它抛出了一个错误,即不支持grant_type,因此我的数据是以JSON而不是x-www-form-urlencoded发送的
  • 是的 Angular 不处理 application/x-www-form-urlencoded; charset=UTF-8 content-type 他必须自己转换对象
【解决方案2】:

所以经过大量的谷歌搜索和思考后,我找到了解决方案,也许有一天它可能会对某人有所帮助。安装了 $html.post() 和 $.ajax() 方法,我将我的数据转换为 x-www-form-urlencoded 作为@Walfrat 和@TheMadDeveloper 的建议,所以我现在可以完美运行的代码看起来像这样:

return $http({
    method: 'POST',
    url: CHEAPWATCHER.config.domain + 'api/Authenticate',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    transformRequest: function (obj) {
        var str = [];
        for (var p in obj)
            str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
            return str.join("&");
        },
        data: data
    }).success(function (result) {
            console.log(result);
});

谢谢大家的帮助!!!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多