有人能告诉我为什么下面的语句没有将post数据发送到指定的url吗?url被调用,但在服务器上,当我打印$_POST -我得到一个空数组。如果我在控制台中打印消息,然后将其添加到数据-它显示了正确的内容。
$http.post('request-url', { 'message' : message });
我也尝试过将数据作为字符串(具有相同的结果):
$http.post('request-url', "message=" + message);
当我以以下格式使用它时,它似乎正在工作:
$http({
method: 'POST',
url: 'request-url',
data: "message=" + message,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});
但是是否有一种方法可以用$http.post() -我总是必须包括头以便它工作吗?我相信上面的内容类型是指定发送数据的格式,但我可以把它作为javascript对象发送吗?
你可以这样设置默认的“Content-Type”:
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
关于数据格式:
美元的http。Post和$http。put方法接受任何JavaScript对象(或字符串)值作为其数据参数。如果data是一个JavaScript对象,默认情况下,它将被转换为JSON字符串。
试着使用这种变化
function sendData($scope) {
$http({
url: 'request-url',
method: "POST",
data: { 'message' : message }
})
.then(function(response) {
// success
},
function(response) { // optional
// failed
});
}
我在使用asp.net MVC时遇到了同样的问题,在这里找到了解决方案
刚接触AngularJS的人有很多困惑,为什么
$http服务简写函数($http.post()等)不会出现
可切换与jQuery的等价物(jQuery.post()等)
不同之处在于jQuery和AngularJS如何序列化和传输数据。从根本上说,问题在于你所选择的服务器语言无法理解AngularJS的传输…jQuery默认使用
Content-Type: x-www-form-urlencoded
以及熟悉的foo=bar&baz=moe序列化。
AngularJS使用
Content-Type: application/json
{"foo": "bar", "baz": "moe"}
JSON序列化,不幸的是一些Web服务器语言—特别是
php—不要本地反序列化。
效果非常好。
CODE
// Your app's root module...
angular.module('MyModule', [], function($httpProvider) {
// Use x-www-form-urlencoded Content-Type
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
/**
* The workhorse; converts an object to x-www-form-urlencoded serialization.
* @param {Object} obj
* @return {String}
*/
var param = function(obj) {
var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
for(name in obj) {
value = obj[name];
if(value instanceof Array) {
for(i=0; i<value.length; ++i) {
subValue = value[i];
fullSubName = name + '[' + i + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
else if(value instanceof Object) {
for(subName in value) {
subValue = value[subName];
fullSubName = name + '[' + subName + ']';
innerObj = {};
innerObj[fullSubName] = subValue;
query += param(innerObj) + '&';
}
}
else if(value !== undefined && value !== null)
query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
}
return query.length ? query.substr(0, query.length - 1) : query;
};
// Override $http service's default transformRequest
$httpProvider.defaults.transformRequest = [function(data) {
return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
}];
});
我知道已经接受了答案。但是,如果这个答案因为任何原因不适合他们,下面的内容可能会对未来的读者有所帮助。
Angular不会像jQuery那样使用ajax。当我尝试按照指南修改angular $httpprovider时,我遇到了其他问题。例如,我使用codeigniter,其中$this->input->is_ajax_request()函数总是失败(这是由另一个程序员编写的,并在全局使用,所以不能改变)说这不是真正的ajax请求。
为了解决这个问题,我接受了延期承诺的帮助。我在Firefox和ie9上进行了测试,效果很好。
我在angular代码的外部定义了以下函数。这个函数使常规jquery ajax调用和返回延迟/承诺(我仍在学习)对象。
function getjQueryAjax(url, obj){
return $.ajax({
type: 'post',
url: url,
cache: true,
data: obj
});
}
然后我用下面的代码称它为角代码。请注意,我们必须使用$scope.$apply()手动更新$scope。
var data = {
media: "video",
scope: "movies"
};
var rPromise = getjQueryAjax("myController/getMeTypes" , data);
rPromise.success(function(response){
console.log(response);
$scope.$apply(function(){
$scope.testData = JSON.parse(response);
console.log($scope.testData);
});
}).error(function(){
console.log("AJAX failed!");
});
这可能不是完美的答案,但它允许我在angular中使用jquery ajax调用,并允许我更新$scope。
我在使用AngularJS和Node.js + Express 4 + Router时也遇到了同样的问题
路由器期望从post的请求中得到数据。如果我遵循Angular Docs中的例子,这个主体总是空的
符号1
$http.post('/someUrl', {msg:'hello word!'})
但如果我把它用在数据中
符号2
$http({
withCredentials: false,
method: 'post',
url: yourUrl,
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: postData
});
编辑1:
否则node.js路由器将期望req中的数据。正文(如使用符号1):
req.body.msg
它还将信息作为JSON有效负载发送。在json和x-www-form-urlencoded中有数组的某些情况下,这是更好的。
它工作。希望能有所帮助。
我也遇到过类似的问题,我在做类似的事情,但没有成功。我的Spring控制器无法读取数据参数。
var paramsVal={data:'"id":"1"'};
$http.post("Request URL", {params: paramsVal});
但是阅读这个论坛和API文档,我试着按照下面的方法,这对我有用。
如果有人也有类似的问题,你也可以试试下面的方法。
$http({
method: 'POST',
url: "Request URL",
params: paramsVal,
headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}
});
请查看https://docs.angularjs.org/api/ng/service/$http#post了解param config的功能。
{data:'"id":"1"'} -字符串或对象的映射将被转换为URL?数据= " id: 1”
与JQuery不同,出于学究的考虑,Angular使用JSON格式进行POST
数据从客户端传输到服务器端(JQuery应用x-www-form-urlencoded,尽管JQuery和Angular使用JSON进行数据输入)。因此有两个部分的问题:在js客户端部分和在你的服务器部分。所以你需要:
把js的Angular客户端部分像这样放:
http({美元
方法:“文章”,
url:“请求url”,
data: {'message': 'Hello world'}
});
AND
写入服务器部分以接收来自客户端的数据(如果是php)。
$data = file_get_contents("php://input");
$ datasondecode = json_decode($data);
$message = $dataJsonDecode->消息;
echo $消息;/ /“Hello world”
注意:$_POST将不起作用!
希望这个方法对我有用,对你也有用。
刚从angular 1.2更新到1.3,在代码中发现了一个问题。转换资源将导致一个无限循环,因为(我认为)$promise再次持有相同的对象。也许它会帮助到某人……
我可以解决这个问题:
[...]
/**
* The workhorse; converts an object to x-www-form-urlencoded serialization.
* @param {Object} obj
* @return {String}
*/
var param = function (obj) {
var query = '', name, value, fullSubName, subName, subValue, innerObj, i;
angular.forEach(obj, function(value, name) {
+ if(name.indexOf("$promise") != -1) {
+ return;
+ }
value = obj[name];
if (value instanceof Array) {
for (i = 0; i < value.length; ++i) {
[...]
我通过以下代码解决了这个问题:
客户端(Js):
$http({
url: me.serverPath,
method: 'POST',
data: data,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
}).
success(function (serverData) {
console.log("ServerData:", serverData);
......
注意,data是一个对象。
在服务器端(ASP。NET MVC):
[AllowCrossSiteJson]
public string Api()
{
var data = JsonConvert.DeserializeObject<AgentRequest>(Request.Form[0]);
if (data == null) return "Null Request";
var bl = Page.Bl = new Core(this);
return data.methodName;
}
和'AllowCrossSiteJsonAttribute'需要跨域请求:
public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
base.OnActionExecuting(filterContext);
}
}
希望这对你有用。
我使用jQuery参数与AngularJS post请求。这里有一个例子……创建AngularJS应用模块,其中myapp在HTML代码中用ng-app定义。
var app = angular.module('myapp', []);
现在让我们创建一个登录控制器和POST电子邮件和密码。
app.controller('LoginController', ['$scope', '$http', function ($scope, $http) {
// default post header
$http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
// send login data
$http({
method: 'POST',
url: 'https://example.com/user/login',
data: $.param({
email: $scope.email,
password: $scope.password
}),
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}).success(function (data, status, headers, config) {
// handle success things
}).error(function (data, status, headers, config) {
// handle error things
});
}]);
我不喜欢解释代码,它足够简单易懂:)注意,param来自jQuery,所以你必须同时安装jQuery和AngularJS才能使它工作。这是一个截图。
希望这对你有帮助。谢谢!
我使用asp.net WCF webservices与angular js和以下代码
工作:
$http({
contentType: "application/json; charset=utf-8",//required
method: "POST",
url: '../../operation/Service.svc/user_forget',
dataType: "json",//optional
data:{ "uid_or_phone": $scope.forgettel, "user_email": $scope.forgetemail },
async: "isAsync"//optional
}).success( function (response) {
$scope.userforgeterror = response.d;
})
希望能有所帮助。
这个问题最终在angular 1.4中使用$httpParamSerializerJQLike解决了
参见https://github.com/angular/angular.js/issues/6039
.controller('myCtrl', function($http, $httpParamSerializerJQLike) {
$http({
method: 'POST',
url: baseUrl,
data: $httpParamSerializerJQLike({
"user":{
"email":"wahxxx@gmail.com",
"password":"123456"
}
}),
headers:
'Content-Type': 'application/x-www-form-urlencoded'
})})
我一直在使用公认的答案的代码(Felipe的代码)一段时间,它工作得很好(谢谢,Felipe!)。
但是,最近我发现它有空对象或数组的问题。
例如,当提交这个对象时:
{
A: 1,
B: {
a: [ ],
},
C: [ ],
D: "2"
}
PHP似乎根本看不到B和C。结果是这样的:
[
"A" => "1",
"B" => "2"
]
看看实际的请求在Chrome显示:
A: 1
:
D: 2
我写了一个替代代码片段。它似乎在我的用例中工作得很好,但我还没有对它进行广泛测试,所以请谨慎使用。
我使用TypeScript,因为我喜欢强类型,但它很容易转换为纯JS:
angular.module("MyModule").config([ "$httpProvider", function($httpProvider: ng.IHttpProvider) {
// Use x-www-form-urlencoded Content-Type
$httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
function phpize(obj: Object | any[], depth: number = 1): string[] {
var arr: string[] = [ ];
angular.forEach(obj, (value: any, key: string) => {
if (angular.isObject(value) || angular.isArray(value)) {
var arrInner: string[] = phpize(value, depth + 1);
var tmpKey: string;
var encodedKey = encodeURIComponent(key);
if (depth == 1) tmpKey = encodedKey;
else tmpKey = `[${encodedKey}]`;
if (arrInner.length == 0) {
arr.push(`${tmpKey}=`);
}
else {
arr = arr.concat(arrInner.map(inner => `${tmpKey}${inner}`));
}
}
else {
var encodedKey = encodeURIComponent(key);
var encodedValue;
if (angular.isUndefined(value) || value === null) encodedValue = "";
else encodedValue = encodeURIComponent(value);
if (depth == 1) {
arr.push(`${encodedKey}=${encodedValue}`);
}
else {
arr.push(`[${encodedKey}]=${encodedValue}`);
}
}
});
return arr;
}
// Override $http service's default transformRequest
(<any>$httpProvider.defaults).transformRequest = [ function(data: any) {
if (!angular.isObject(data) || data.toString() == "[object File]") return data;
return phpize(data).join("&");
} ];
} ]);
它的效率比Felipe的代码低,但我认为这无关紧要,因为与HTTP请求本身的整体开销相比,它应该是即时的。
现在PHP显示:
[
"A" => "1",
"B" => [
"a" => ""
],
"C" => "",
"D" => "2"
]
据我所知,让PHP识别B.a和C是空数组是不可能的,但至少键会出现,当代码依赖于某个结构时,这很重要,即使它内部实际上是空的。
还要注意,它将未定义的和null转换为空字符串。
没有找到如何使用$http的完整代码片段。Post方法将数据发送到服务器,以及为什么在这种情况下它不工作。
以下代码段的解释…
我使用jQuery $。param函数将JSON数据序列化为www post data
在配置变量中设置Content-Type,该变量将随angularJS $http请求一起传递。通知服务器我们将以WWW Post格式发送数据。
注意$ http。post方法,我发送的第一个参数作为url,第二个参数作为数据(序列化)和第三个参数作为配置。
剩下的代码是自己理解的。
$scope.SendData = function () {
// use $.param jQuery function to serialize data from JSON
var data = $.param({
fName: $scope.firstName,
lName: $scope.lastName
});
var config = {
headers : {
'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
}
}
$http.post('/ServerRequest/PostDataResponse', data, config)
.success(function (data, status, headers, config) {
$scope.PostDataResponse = data;
})
.error(function (data, status, header, config) {
$scope.ResponseDetails = "Data: " + data +
"<hr />status: " + status +
"<hr />headers: " + header +
"<hr />config: " + config;
});
};
查看$http的代码示例。Post方法在这里。
通过使用非常简单的方法,我们可以这样做:
$http({
url : "submit_form_adv.php",
method : 'POST',
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 : {sample_id : 100, sample_name: 'Abin John'},
}).success(function(data, status, headers, config) {
}).error(function(ata, status, headers, config) {
});
It's not angular's fault. Angular is designed to work in JSON world. So when $http service send AJAX request, it send all your data as a payload, not as form-data so that your backend application can handle it. But jQuery does some things internally. You instruct jQuery's $ajax module to bind form-data as JSON but before sending AJAX request, it serialized JSON and add application/x-www-form-urlencoded header. This way your backend application able to received form-data in form of post parameters and not JSON.
但是你可以修改angular $http服务的默认行为
添加标题
序列化json
$httpParamSerializerJQLike是angular的内置服务,它以同样的方式序列化json。jQuery的参数。
$http({
method: 'POST',
url: 'request-url',
data: $httpParamSerializerJQLike(json-form-data),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8;'
}
});
如果你需要一个插件先将表单数据序列化成JSON,可以使用这个插件https://github.com/marioizquierdo/jquery.serializeJSON
如果使用Angular >= 1.4,下面是使用Angular提供的序列化器的最简洁的解决方案:
angular.module('yourModule')
.config(function ($httpProvider, $httpParamSerializerJQLikeProvider){
$httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get());
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
});
然后你可以简单地在你的应用的任何地方做这个:
$http({
method: 'POST',
url: '/requesturl',
data: {
param1: 'value1',
param2: 'value2'
}
});
它会正确地将数据序列化为param1=value1¶m2=value2,并将其发送到/requesturl,并使用application/x-www-form-urlencoded;charset=utf-8内容类型报头,因为它通常是端点上POST请求所期望的。
博士TL;
在我的研究中,我发现这个问题的答案有很多种;一些是非常复杂的,依赖于自定义函数,一些依赖于jQuery和一些是不完整的,建议你只需要设置头。
如果您只是设置Content-Type报头,端点将看到POST数据,但它不会是标准格式,因为除非您提供一个字符串作为数据,或者手动序列化数据对象,否则在默认情况下,它都将被序列化为JSON,并且可能在端点被错误地解释。
例如,如果在上面的例子中没有设置正确的序列化器,它将在端点中被视为:
{"param1":"value1","param2":"value2"}
这可能导致意想不到的解析,例如ASP。NET将其视为空参数名,用{"param1":"value1","param2":"value2"}作为值;或者Fiddler以另一种方式解释它,用{"param1":"value1","param2":"value2"}作为参数名,用null作为值。
这可能是一个很晚的答案,但我认为最合适的方法是使用angular在使用$httpParamSerializer执行“get”请求时使用的同一段代码,它将不得不注入到你的控制器中
所以你可以简单地做下面的事情,而不需要使用Jquery,
美元http.post (url, httpParamSerializer美元({参数:val}))
app.controller('ctrl',function($scope,$http,$httpParamSerializer){
$http.post(url,$httpParamSerializer({param:val,secondParam:secondVal}));
}
在我的例子中,我是这样解决问题的:
var deferred = $q.defer();
$http({
method: 'POST',
url: 'myUri',
data: $.param({ param1: 'blablabla', param2: JSON.stringify(objJSON) }),
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(
function(res) {
console.log('succes !', res.data);
deferred.resolve(res.data);
},
function(err) {
console.log('error...', err);
deferred.resolve(err);
}
);
return deferred.promise;
您需要使用JSON。为每个包含JSON对象的参数进行stringify,然后使用"$. stringify "构建数据对象。param”:-)
注意:我的“objJSON”是一个JSON对象,包含数组,整数,字符串和html内容。他的总大小是>3500个字符。
只是提出一个现代化版本的@FelipeMiosso的答案:
.config(["$httpProvider", function ($httpProvider) {
function buildKey(parentKey, subKey) {
return parentKey + "[" + subKey + "]";
}
function buildObject(key, value) {
var object = {};
object[key] = value;
return object;
}
function join(array) {
return array.filter(function (entry) {
return entry;
}).join("&");
}
function arrayToQueryString(parentKey, array) {
return join(array.map(function (value, subKey) {
return toQueryString(buildObject(buildKey(parentKey, subKey), value));
}));
}
function objectToQueryString(parentKey, object) {
return join(Object.keys(object).map(function (subKey) {
return toQueryString(buildObject(buildKey(parentKey, subKey), object[subKey]));
}));
}
function toQueryString(input) {
return join(Object.keys(input).map(function (key) {
var value = input[key];
if (value instanceof Array) {
return arrayToQueryString(key, value);
} else if (value instanceof Object) {
return objectToQueryString(key, value);
} else if (undefined !== value && null !== value) {
return encodeURIComponent(key) + "=" + encodeURIComponent(value);
} else {
return "";
}
}));
}
function isQueryStringEligible(input) {
return null !== input && "object" === typeof input && "[object File]" !== String(input);
}
var interceptor = [function () {
return {
request: function (config) {
if (0 <= ["post", "put", "patch"].indexOf(config.method.toLowerCase()) && isQueryStringEligible(config.data)) {
config.headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
config.data = toQueryString(config.data);
}
return config;
}
};
}];
$httpProvider.interceptors.push(interceptor);
}])
ES6版本:
.config(["$httpProvider", function ($httpProvider) {
"use strict";
const buildKey = (parentKey, subKey) => `${parentKey}[${subKey}]`;
const buildObject = (key, value) => ({ [key]: value });
const join = (array) => array.filter((entry) => entry).join("&");
const arrayToQueryString = (parentKey, array) =>
join(array.map((value, subKey) =>
toQueryString(buildObject(buildKey(parentKey, subKey), value))));
const objectToQueryString = (parentKey, object) =>
join(Object.keys(object).map((subKey) =>
toQueryString(buildObject(buildKey(parentKey, subKey), object[subKey]))));
const toQueryString = (input) => join(Object.keys(input).map((key) => {
const value = input[key];
if (value instanceof Array) {
return arrayToQueryString(key, value);
} else if (value instanceof Object) {
return objectToQueryString(key, value);
} else if (undefined !== value && null !== value) {
return `${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
} else {
return "";
}
}));
const isQueryStringEligible = (input) =>
null !== input && "object" === typeof input && "[object File]" !== String(input);
const interceptor = [() => ({
request(config) {
if (0 <= ["post", "put", "patch"].indexOf(config.method.toLowerCase()) && isQueryStringEligible(config.data)) {
config.headers["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
config.data = toQueryString(config.data);
}
return config;
}
})];
$httpProvider.interceptors.push(interceptor);
}])