【问题标题】:Accessing API with $http POST Content-Type application/x-www-form-urlencoded使用 $http POST Content-Type application/x-www-form-urlencoded 访问 API
【发布时间】:2017-09-22 12:57:37
【问题描述】:

我正在尝试访问此 REST API,它接受三个参数: stationId, crusherId, monthYear 我在 AngularJS 中这样做是:

$http({
        //headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
        //headers: {'Content-Type': 'application/json; charset=UTF-8'},
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 
            'Accept':       'application/json'
        },
        url:    'https://myurl../api/getHPData',
        method: 'POST',
        data: {
            stationId: 263, 
            crusherId: 27, 
            monthYear: '2016-4'
        }
    })

    .then(function(data, status, headers, config) {
            //console.log(JSON.stringify(response));
            console.log(data);
     })
    .catch(function(error){
            //console.log("Error: " + JSON.stringify(error));
            console.log(error);
        })

但我总是得到这个:

对象{数据:"{"result":"false"}",状态:200,配置:对象,状态文本:"OK",标题:函数}

{"data":"{\"result\":\"false\"}","status":200,"config":{"method":"POST","transformRequest":[null] ,"transformResponse":[null],"headers":{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","Accept":"application/json"},"url":"https://myurl../api/getHPData","data":{"stationId":263,"crusherId":27,"monthYear":" 2016-4"}},"statusText":"OK"}

如果我将header Content-Type 更改为:

headers: {'Content-Type': 'application/json; charset=UTF-8'},

它给出:

Object {data: null, status: -1, config: Object, statusText: "",headers: function}

{"data":null,"status":-1,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"headers": {“内容类型”:“应用程序/json; charset=UTF-8","Accept":"应用程序/json,文本/纯文本, /"},"url":"https://myurl../api/getHPData","data":{"stationId":263,"crusherId":27,"monthYear":"2016-4"}}, "statusText":""}

我做错了什么,请帮助我。

Plunker 来了:

https://plnkr.co/edit/57SiCdBZB2OkhdR03VOs?p=preview

(编辑)

注意: 我可以在jQuery 中这样做:

<script>
$(document).ready(function() {
        get_homepage_data(263, 27, '2016-04');

        function get_homepage_data(stationIds, crusherIds, date) {
            var url = "https://myurl../api/getHPData";
            var data_to_send = {
                'stationId': stationIds, 
                'crusherId': crusherIds,
                'monthYear': date
            };

            console.log("Value is: " + JSON.stringify(data_to_send));
            //change sender name with account holder name
            //        console.log(data_to_send)
            $.ajax({
                url: url,
                method:   'post',
                dataType: 'json',
                //contentType: 'application/json',
                data: data_to_send,
                processData: true,
                // crossDomain: true,
                beforeSend: function () {
                }
                , complete: function () {}
                , success: function (result1) {
                    var Result = JSON.parse(result1);
                    var value_data = Result["valueResult"];
                    var foo = value_data["gyydt"];

                    console.log("Log of foo is: " + foo);

                    var foo2 = 0;
                    // 10 lac is one million.
                    foo2 = foo / 1000000 + ' million';

                    console.log(JSON.stringify(value_data["gyydt"]) + " in million is: " + foo2);
                }
                , error: function (request, error) {
                    return false;
                }
            });
        }   
    }); // eof Document. Ready  
</script>

上面脚本的输出是script是:

  • 值为:{"stationId":263,"crusherId":27,"monthYear":"2016-04"}
  • XHR 完成加载:POST “https://myurl../api/getHPData”。
  • foo 的日志是:26862094
  • “26862094”百万为:2686.2094万

这是完美的。 :)

【问题讨论】:

    标签: angularjs rest post angular-http


    【解决方案1】:

    The documentation 表示 stationId 和 crusherId 参数应该是字符串数组。此外,您似乎正在发送 JSON 数据,因此请确保正确设置该标头。

    $http({
        headers: {
            'Content-Type': 'application/json', 
            'Accept':       'application/json'
        },
        url:    'https://fnrc.gov.ae/roayaservices/api/getHPData',
        method: 'POST',
        data: {
            stationId: ['263'], 
            crusherId: ['27'], 
            monthYear: '2016-4'
        }
    })
    

    当我更改您的 plunkr 中的代码以使用上面更正的代码时,我收到以下响应:“请求的资源不支持 http 方法'OPTIONS'。

    正如正确提到的另一个(现已删除)答案,这意味着存在 CORS 问题。浏览器试图在发出跨域请求之前发送“预检”请求,而服务器不知道如何处理它。您还可以在 Chrome 控制台中看到此消息:

    XMLHttpRequest 无法加载 https://fnrc.gov.ae/roayaservices/api/getHPData。回应 预检具有无效的 HTTP 状态代码 405

    【讨论】:

    • 不工作,我也试过了,它返回:{"data":"{\"result\":\"false\"}","status":200,"config":{"method":"POST","transformRequest":[null],"transformResponse":[null],"headers":{"Content-Type":"application/x-www-form-urlencoded; charset=UTF-8","Accept":"application/json"},"url":"https://fnrc.gov.ae/roayaservices/api/getHPData","data":{"stationId":[263],"crusherId":[27],"monthYear":"2016-4"}},"statusText":"OK"}
    • @fWd82 因为您要发送 JSON,您还应该将您的内容类型设置为 JSON。我会更新我的答案。
    • 感谢您更新您的答案,它仍然给我同样的错误。请注意,此错误来自.catch(function(error)。我不知道该怎么办。你能看看我在我的问题中包含的 Plnkr 链接吗?
    • @fWd82 不幸的是,我认为我无法提供更多帮助。看起来您符合 API,所以我无法想象它为什么会返回“false”(并且响应背后的含义在该文档中没有明确说明)。祝你好运,对不起,我无法提供更多帮助!
    • @fWd82 谢谢!很高兴有人能够帮助您。
    【解决方案2】:

    发布 URL 编码的表单数据时,使用 $httpParamSerializer service 转换请求:

    $http({
        headers: {'Content-Type':'application/x-www-form-urlencoded; charset=UTF-8'},
        url: 'https://fnrc.gov.ae/roayaservices/api/getHPData',
        method: 'POST',
        transformRequest: $httpParamSerializer,
        transformResponse: function (x) {
          return angular.fromJson(angular.fromJson(x));
        },
        data: {
          "stationId": 263,
          "crusherId": 27,
          "monthYear": '2016-04'
        }
    }) 
      .then(function(response) {
        console.log(response);
        $scope.res = response.data;
        console.log($scope.res);
    });
    

    通常 $http 服务会自动解析来自 JSON 编码对象的结果,但此 API 会返回一个已从对象双重序列化的字符串。 transformResponse 函数解决了这个问题。

    DEMO on PLNKR

    【讨论】:

    • 你好。谢谢您的回答。它现在正在工作。哇。 :) 但是你能告诉我:How would I know that I will be using: application/x-www-form-urlencoded 我怎么知道string 是双重序列化的。你能补充一些细节吗?这样它将来也可以帮助我。谢谢
    • 我需要:gytotal 的值,里面是:valueResult,你能告诉我怎么做吗?
    • parseFloat(response.data.valueResult.gytotal)
    • 这可能会有所帮助。但是,我使用的是旧版本的 AngularJS (1.2.21)。其中“$httpParamSerializer”不可用。
    最近更新 更多