使用 Angular.js 的 HTTP POST

Posted

技术标签:

【中文标题】使用 Angular.js 的 HTTP POST【英文标题】:HTTP POST using Angular.js 【发布时间】:2013-03-20 09:38:26 【问题描述】:

我是新手,我想使用 Angular.js 发出 HTTP POST 请求。我正在访问具有只是 POST 变量的参数的 php 脚本。每个脚本返回的是一个 JSON 字符串。通常在 html 表单中,您可以发出如下请求:

<form method="post" action="url.php">
<input name="this">
<input name="that">
<input value="Submit">
</form>

根据您的输入,点击提交后,JSON data1 将返回如下内容: "code" : 1

我无权访问脚本或托管它们的服务器。

我想知道 Angular.js 是否可以读取 JSON 数据 1,将该数据 1 与我的 JSON 数据 2 中定义的内容相匹配,然后将它们输出到我的视图 (&lt;pre&gt;data2&lt;/pre&gt;)。

例如,如果检索到 "code" : 1 ,我希望我的 JSON 输出代码 #1 的值:

 "code" : [
   1: "User already logged in." , 
   2: "Wrong parameters, try again.", 
   3: "etc., etc." 
 ] 
;

这是我的尝试:

<form ng-controller="PhpCtrl" name="f1">
<input type="text" name="name">
<input type="text" name="password">
<pre ng-model="codeStatus">codeStatus</pre>
<input type="submit" ng-click="add()" value="Submit">
</form>

function PhpCtrl($scope, $http, $templateCache) 
    $scope.method = 'POST';
    $scope.url = 'url.php';
    $scope.codeStatus = "";

    $scope.add = function() 

        $http(
            method: $scope.method, 
            url: $scope.url,
            headers: 'Content-Type': 'application/x-www-form-urlencoded',  
            cache: $templateCache
        ).
        success(function(response) 
            $scope.codeStatus = response.data;
        ).
        error(function(response) 
            $scope.codeStatus = response || "Request failed";
        );
        return false;   
    ;

到目前为止,它发布到视图的所有内容都是“请求失败”,哈哈,虽然它正在处理 HTTP/1.1 200。我知道我还有很长的路要走,但我会很感激任何帮助。一旦我弄清楚如何将正确的 JSON data1 发布到视图中,下一步就是匹配并输出相应的 data2。提前谢谢!

【问题讨论】:

可能请求失败是因为您正在执行发布请求而没有发送数据,请尝试将所有表单字段放在 FormData 对象中并通过添加此data: FormData 将其与请求一起发送为将所有表单字段放入 $http 请求后的参数或标题不正确。希望对您有所帮助。 感谢您的回复。我不确定我这样做是否正确,但我是否只是将 FormData 中的表单数据包装为“JSON 对象”?我试过这个pastebin.com/QMZSr4AZ,它仍在处理“请求失败”错误,所以我猜我仍然无法发送数据。 2 件事:1) 你不应该在 $scope 上设置这些值,$scope 是为了模型绑定,它上面的所有值都是 Watched,它们的值应用于同名字段,这对性能有影响。只需将它们设置为局部变量,如 var method = 'POST',它们将作为闭包的一部分在 http 函数中使用。 2) 你知道如何进入 Chrome/Firefox 中的 JS 调试器吗?使用它来检查响应。在 Chrome 右上角 > 开发者工具中,如果添加调试器,则需要网络选项卡和控制台;错误函数的行。 嗨,克里斯,感谢您的评论和建议! $scope 上的模型绑定是有意义的,所以我会记得使用局部变量。而且我玩过 JS 调试器,但是由于我在本地进行测试,所以它一直在抛出关于同源策略的错误,所以我暂时使用的是 Firefox。 【参考方案1】:

实际上问题出在 PHP 的后端,您没有像往常一样检索发布的数据,这对我有用:

function PhpCtrl($scope, $http, $templateCache) 
  var method = 'POST';
  var url = 'url.php';
  $scope.codeStatus = "";
  $scope.add = function() 
    var FormData = 
      'name' : document.f1.name.value,
      'password' : document.f1.password.value
    ;
    $http(
      method: method,
      url: url,
      data: FormData,
      headers: 'Content-Type': 'application/x-www-form-urlencoded',
      cache: $templateCache
    ).
    success(function(response) 
        $scope.codeStatus = response.data;
    ).
    error(function(response) 
        $scope.codeStatus = response || "Request failed";
    );
    return false;
  ;

在 PHP 文件中:

$data = json_decode(file_get_contents("php://input"));
echo $data->name;

希望对您有所帮助。

【讨论】:

Yahya,开发人员尝试实现该脚本,但它说它无法从非对象获取属性“名称”。行 (echo $data->name;) 是否必要? 不,这只是一个示例,之前的行是您需要进行数据处理然后回显您想要的返回消息的行。 我的 php 版本是 PHP 5.5.3,这对我来说很好用 #ta7yaISI #Ta7yaTounes parse_str(file_get_contents('php://input'), $data); 使用 PHP 5.3.13 为我工作。 这是一个巨大的帮助!非常感谢@YahyaKACEM。干杯!【参考方案2】:

一种可能的替代方法是使用 XHR 请求处理程序来序列化 POST 请求的负载。

$httpProvider.interceptors.push(['$q', function($q) 
    return 
        request: function(config) 
            if (config.data && typeof config.data === 'object') 
                // Check https://gist.github.com/brunoscopelliti/7492579 for a possible way to implement the serialize function.
                config.data = serialize(config.data);
            
            return config || $q.when(config);
        
    ;
]);

此外,如果您之前没有这样做,您还必须更改 post 请求的默认 content-type 标头:

$http.defaults.headers.post["Content-Type"] = 
    "application/x-www-form-urlencoded; charset=UTF-8;";

最近我在我的博客上写了一篇文章,您可以在其中找到有关此方法的更多信息,以及XHR request interceptor。

【讨论】:

【参考方案3】:

相当老的帖子......但我认为我的解决方案也可能对其他人有用。

我不喜欢

json_decode(file_get_contents("php://input"));

解决方案...基本上是因为它似乎违反了良好的做法(我可能错了)

这就是我解决它的方法(适应上面的例子)

function PhpCtrl($scope, $http, $templateCache) 
  var method = 'POST';
  var url = 'url.php';
  $scope.codeStatus = "";
  $scope.add = function() 
    var FormData = 
      'name' : document.f1.name.value,
      'password' : document.f1.password.value
    ;
    $http(
      method: method,
      url: url,
      data: $.param('data' : FormData),
      headers: 'Content-Type': 'application/x-www-form-urlencoded',
      cache: $templateCache
    ).
    success(function(response) 
        $scope.codeStatus = response.data;
    ).
    error(function(response) 
        $scope.codeStatus = response || "Request failed";
    );
    return false;
  ;

完成后

data: $.param('data' : FormData),
headers: 'Content-Type': 'application/x-www-form-urlencoded',

您可以访问通常在 PHP 中访问的数据

$data = $_POST['data'];

【讨论】:

请求数据中真的需要$templateCache吗? 我不知道在回答这个问题时是否有任何改变,但是 $.param() 对我来说是未定义的,我的工作是使用:$httpParamSerializerJQLike(FormData) 好吧,看来你需要 jQuery 才能工作。否则 $.param 未定义。 是的...对不起...应该提到这使用了jQuery的$.params()函数 这里是独立的参数函数:var param = function(data) var returnString = ''; for (var d in data) if (data.hasOwnProperty(d)) returnString += d + '=' + data[d] + '&amp;'; return returnString.slice( 0, returnString.length - 1 ); ;

以上是关于使用 Angular.js 的 HTTP POST的主要内容,如果未能解决你的问题,请参考以下文章

节点 js busboy 不使用 angular js $http post 发出事件

如何在Angular.js $http.post中指定dataType:'json'?

angular.js跨域post解决方案

通过 Angular JS $http.post 使用 slim 框架时出现 404 无效的 http 状态代码

Angular.js $http.post TypeError:无法读取未定义的属性“数据”

angular js $http服务使用