我想使用Angular App中的
$http
进行服务器端的AJAX调用。 为发送参数,我尝试了以下操作:
$http({
method: "post",
url: URL,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: $.param({username: $scope.userName, password: $scope.password})
}).success(function(result){
console.log(result);
});
这是可行的,但在
$.param
上也使用jQuery。为了消除对jQuery的依赖,我尝试了:data: {username: $scope.userName, password: $scope.password}
,但这似乎失败了。然后我尝试了
params
:params: {username: $scope.userName, password: $scope.password}
,但这似乎也失败了。然后我尝试了
JSON.stringify
:data: JSON.stringify({username: $scope.userName, password: $scope.password})
我找到了这些可能的答案,但未成功。难道我做错了什么?我确定AngularJS会提供此功能,但是如何?
#1 楼
我认为您需要做的是将数据从对象转换为JSON字符串而不是JSON字符串。从Ben Nadel的博客开始。
默认情况下,$ http服务将转换通过将数据序列化为JSON然后将其发布为content-
类型“ application / json”将请求传出。当我们想将值发布为FORM
时,我们需要更改序列化算法并使用内容类型“ application / x-www-form-urlencoded”发布数据。 br />
此处的示例。
$http({
method: 'POST',
url: url,
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: {username: $scope.userName, password: $scope.password}
}).then(function () {});
UPDATE
要使用AngularJS V1.4中添加的新服务,请参见
使用URL编码变量仅AngularJS服务
评论
感谢您不使用JQuery!
– OverMars
2015年1月12日17:50
如果我需要提交多部分/表单数据怎么办?
– Dejell
15年1月13日在7:57
只要角度将jqLite嵌入angular.element下,您就可以简单地返回angular.element.param(obj);。
–子弹
15年1月26日在15:43
@Vicary请记住,jqLite中未实现param()-code.angularjs.org/1.3.14/docs/api/ng/function/angular.element
– Alex Pavlov
15 Mar 25 '15 at 0:35
这是另一种方法var obj = {a:1,b:2}; Object.keys(obj).reduce(function(p,c){return p.concat([encodeURIComponent(c)+“ =” + encodeURIComponent(obj [c])]);},[])。join(' &');
–test30
16-09-14在22:09
#2 楼
仅使用AngularJS服务进行URL编码变量在AngularJS 1.4及更高版本中,两个服务可以处理POST请求的URL编码数据过程,从而无需使用
transformRequest
或使用外部依赖项来处理数据像jQuery:$httpParamSerializerJQLike
-受jQuery .param()
启发的序列化器(推荐)$httpParamSerializer
-Angular自身用于GET请求的序列化器示例用法
$http({
url: 'some/api/endpoint',
method: 'POST',
data: $httpParamSerializerJQLike($scope.appForm.data), // Make sure to inject the service you choose to the controller
headers: {
'Content-Type': 'application/x-www-form-urlencoded' // Note the appropriate header
}
}).then(function(response) { /* do something here */ });
查看更详细的Plunker演示
$httpParamSerializerJQLike
和$httpParamSerializer
有何不同通常,对于复杂的数据结构,
$httpParamSerializer
似乎比$httpParamSerializerJQLike
使用更少的“传统” URL编码格式。例如(忽略括号的百分比编码):•编码数组
{sites:['google', 'Facebook']} // Object with array property
sites[]=google&sites[]=facebook // Result with $httpParamSerializerJQLike
sites=google&sites=facebook // Result with $httpParamSerializer
•编码对象
{address: {city: 'LA', country: 'USA'}} // Object with object property
address[city]=LA&address[country]=USA // Result with $httpParamSerializerJQLike
address={"city": "LA", country: "USA"} // Result with $httpParamSerializer
评论
我们如何在工厂内部的$ resource上使用它?
–静物
2015年10月9日在10:17
应该是$ http。({...而不是$ http.post({...
–卡洛斯·格拉纳多斯(Carlos Granados)
2015年11月7日14:30在
@CarlosGranados感谢您的关注。在此处和在Plunker演示中更正了此错字。
– Boaz
15年11月7日在16:15
从jQuery迁移到AngularJS后,此方法非常有效
– zero298
16-2-18在22:47
这是我正在寻找的特定于AngularJS的答案。我希望张贴者会选择这作为最佳答案。
–Marty Chang
16年5月1日下午4:08
#3 楼
所有这些看起来都像是过度杀伤(或不起作用)...只需执行以下操作:$http.post(loginUrl, `username=${ encodeURIComponent(username) }` +
`&password=${ encodeURIComponent(password) }` +
'&grant_type=password'
).success(function (data) {
评论
最后是一些常识
– jlewkovich
15年7月28日在17:53
这不会使用错误的内容类型标头发送请求吗?
–菲尔
16年7月22日在5:24
它对我有用...不确定标题是什么,但是请求有效,并且允许成功进行身份验证。您为什么不进行测试并告诉我们。
–塞尔吉·萨根(Serj Sagan)
16年7月23日在6:51
@Phil我猜想这可能取决于服务器,我的请求很糟糕,直到我添加了{标头:{'Content-Type':'application / x-www-form-urlencoded'}}作为配置arg或供应使用$ http(config)构造函数,如moices的答案所示。无论哪种方式,这都优于公认的答案,因为它不会带来任何神奇的变化,并且不需要用户提供一些辅助服务。谢谢!
– Bungle先生
16年11月17日在20:05
#4 楼
问题是JSON字符串格式,您可以在数据中使用简单的URL字符串:$http({
method: 'POST',
url: url,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: 'username='+$scope.userName+'&password='+$scope.password
}).success(function () {});
评论
您必须使用encodeURIComponent($ scope.userName)对数据进行url编码,否则如果用户输入“&myCustomParam = 1”之类的值,则参数将被破坏
–伊凡·胡尚克(IvanHušnjak)
2015年9月9日在18:28
这是唯一对我有用的答案!我跳过了成功,但是$ http格式很好
– xenteros
16年7月19日在11:38
#5 楼
这是应该的方式(请不要更改后端...肯定不可以...如果您的前端堆栈不支持application/x-www-form-urlencoded
,则将其丢弃...希望AngularJS可以!$http({
method: 'POST',
url: 'api_endpoint',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: 'username='+$scope.username+'&password='+$scope.password
}).then(function(response) {
// on success
}, function(response) {
// on error
});
与AngularJS 1.5一样魅力十足。
人们,请给我一些建议:
在处理
.then(success, error)
时请使用诺言$http
,请忘记.sucess
和.error
回调(因为它们已被弃用)在angularjs网站上,“您不能再使用JSON_CALLBACK字符串作为占位符来指定回调参数值应该放在哪里。”
如果您的数据模型比用户名和密码更复杂,您仍然可以按照上面的建议进行操作。
$http({
method: 'POST',
url: 'api_endpoint',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: json_formatted_data,
transformRequest: function(data, headers) {
return transform_json_to_urlcoded(data); // iterate over fields and chain key=value separated with &, using encodeURIComponent javascript function
}
}).then(function(response) {
// on succes
}, function(response) {
// on error
});
encodeURIComponent
的文档可以在这里找到#6 楼
如果是表单,请尝试将标头更改为:headers[ "Content-type" ] = "application/x-www-form-urlencoded; charset=utf-8";
,如果不是表单和简单的json,请尝试以下标头:
headers[ "Content-type" ] = "application/json";
评论
没有收到任何东西。我仍然收到空白的$ _POST数组。
– Veer Shrivastav
2014年7月20日在11:36
这是您的控制器中的$ http呼叫吗?
– V31
2014年7月25日在17:36
还有一件事是您的服务器端php?
– V31
2014年7月25日在18:07
我已经找到了相同的解决方案,您仍然遇到@Veer问题吗?
– V31
2014年7月29日在5:20
#7 楼
在$ http docs中,这应该可以工作。. $http.post(url, data,{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
.success(function(response) {
// your code...
});
评论
@Kevin我对此不太确定,但是..当我尝试发送一个字符串时,它显示了一个错误
– Srinath
2014年7月12日在7:10
@KevinB好..我明白了..我认为在发送字符串时需要更改标题..stackoverflow.com / a / 20276775/2466168
– Srinath
2014年7月12日7:20
请注意,发送正确的标头不会影响仍然需要以一种或另一种方式进行urlencode的数据。
– Boaz
2015年9月1日在8:55
数据仍以json发送,您必须将数据编码为x-www-form-urlencoded,仅添加标头是不够的
–wendellmva
16年2月28日在16:10
#8 楼
$http({
method: "POST",
url: "/server.php",
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
data: "name='Олег'&age='28'",
}).success(function(data, status) {
console.log(data);
console.log(status);
});
评论
仅代码答案对社区没有用。请看看如何回答
–阿帕地尔
17年8月18日在10:17
#9 楼
您需要发布普通的javascript对象,没有其他内容 var request = $http({
method: "post",
url: "process.cfm",
transformRequest: transformRequestAsFormPost,
data: { id: 4, name: "Kim" }
});
request.success(
function( data ) {
$scope.localData = data;
}
);
如果您将php作为后端,则需要做更多修改。修复php服务器端
评论
那完全不是他想要的,他特别地问他如何将它们以x-www-form-urlencoded的形式获得,因为他遇到了发布json内容的问题。
–ppetermann
15年1月16日在16:23
@ppetermann您是否已在降低投票权之前检查了问题的编辑历史记录。
–harishr
15年1月20日在13:07
#10 楼
尽管答案很晚,但我发现有角度的UrlSearchParams对我来说效果很好,它也照顾参数的编码。let params = new URLSearchParams();
params.set("abc", "def");
let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded'});
let options = new RequestOptions({ headers: headers, withCredentials: true });
this.http
.post(UrlUtil.getOptionSubmitUrl(parentSubcatId), params, options)
.catch();
#11 楼
这对我有用。我在前端使用angular,在后端使用laravel php。在我的项目中,angular web将json数据发送到laravel后端。这是我的角度控制器。
var angularJsApp= angular.module('angularJsApp',[]);
angularJsApp.controller('MainCtrl', function ($scope ,$http) {
$scope.userName ="Victoria";
$scope.password ="password"
$http({
method :'POST',
url:'http://api.mywebsite.com.localhost/httpTest?callback=JSON_CALLBACK',
data: { username : $scope.userName , password: $scope.password},
headers: {'Content-Type': 'application/json'}
}).success(function (data, status, headers, config) {
console.log('status',status);
console.log('data',status);
console.log('headers',status);
});
});
这是我的php后端laravel控制器。
public function httpTest(){
if (Input::has('username')) {
$user =Input::all();
return Response::json($user)->setCallback(Input::get('callback'));
}
}
这是我的laravel路由
Route::post('httpTest','HttpTestController@httpTest');
浏览器中的结果是
状态200
数据JSON_CALLBACK({“ username”:“ Victoria”,“ password”:“ password”,“ callback”:“ JSON_CALLBACK”}));
/> httpTesting.js:18标头函数(c){a ||(a = sc(b));返回
c?a [K(c())] || null:a}
有一个叫做postman的chrome扩展程序。您可以使用它来测试后端网址是否正常。
https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=zh-CN
希望我的回答对您有所帮助。
评论
我不知道实际的问题是什么,但是您是否尝试过$ http({method:'post',url:URL,data:{username:$ scope.userName,password:$ scope.password}}));您的第一个方法应该起作用,是否已定义$ scope.userName?为什么不尝试数据:数据?
@KevinB:对不起..我进行了正确的编辑。
@mritunjay:对不起..我进行了编辑..我尝试了相同的操作。
@Veer起作用了还是还是有问题?