Как я могу публиковать данные в виде данных формы, а не полезной нагрузки запроса?

В приведенном ниже коде AngularJS $http Метод вызывает URL-адрес и отправляет объект xsrf как «Запрос полезной нагрузки» (как описано на вкладке «Сеть отладчика Chrome»). JQuery $.ajax Метод выполняет тот же вызов, но отправляет xsrf как «Данные формы».

Как я могу заставить AngularJS отправлять xsrf как данные формы вместо полезной нагрузки запроса?

var url = 'http://somewhere.com/';
var xsrf = {fkey: 'xsrf key'};

$http({
method: 'POST',
url: url,
data: xsrf
}).success(function () {});

$.ajax({
type: 'POST',
url: url,
data: xsrf,
dataType: 'json',
success: function() {}
});

508

Решение

Следующая строка должна быть добавлена ​​к переданному объекту $ http:

headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}

И переданные данные должны быть преобразованы в строку в кодировке URL:

> $.param({fkey: "key"})
'fkey=key'

Итак, у вас есть что-то вроде:

$http({
method: 'POST',
url: url,
data: $.param({fkey: "key"}),
headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'}
})

От: https://groups.google.com/forum/#!msg/angular/5nAedJ1LyO0/4Vj_72EZcDsJ

ОБНОВИТЬ

Чтобы использовать новые сервисы, добавленные с AngularJS V1.4, см.

595

Другие решения

Если вы не хотите использовать jQuery в решении, вы можете попробовать это. Решение схвачено отсюда https://stackoverflow.com/a/1714899/1784301

$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: xsrf
}).success(function () {});
192

Продолжающаяся путаница вокруг этой проблемы вдохновила меня написать сообщение в блоге об этом. Решение, которое я предлагаю в этом посте, лучше, чем ваше текущее решение с самым высоким рейтингом, потому что оно не ограничивает вас параметризацией объекта данных для вызовов службы $ http; то есть с моим решением вы можете просто продолжать передавать фактические объекты данных в $ http.post () и т. д. и при этом достигать желаемого результата.

Кроме того, ответ с самым высоким рейтингом основан на включении полного jQuery на странице для функции $ .param (), в то время как мое решение не зависит от jQuery и полностью готово для AngularJS.

http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

Надеюсь это поможет.

91

Я взял несколько других ответов и сделал что-то немного чище .config() вызовите конец вашего angular.module в вашем app.js:

.config(['$httpProvider', function ($httpProvider) {
// Intercept POST requests, convert to standard form encoding
$httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
$httpProvider.defaults.transformRequest.unshift(function (data, headersGetter) {
var key, result = [];

if (typeof data === "string")
return data;

for (key in data) {
if (data.hasOwnProperty(key))
result.push(encodeURIComponent(key) + "=" + encodeURIComponent(data[key]));
}
return result.join("&");
});
}]);
82

Начиная с AngularJS v1.4.0, есть встроенный $httpParamSerializer сервис, который преобразует любой объект в часть HTTP-запроса в соответствии с правилами, перечисленными в страница документов.

Это можно использовать так:

$http.post('http://example.com', $httpParamSerializer(formDataObj)).
success(function(data){/* response status 200-299 */}).
error(function(data){/* response status 400-999 */});

Помните, что для правильной формы сообщения, Content-Type заголовок должен быть изменен. Чтобы сделать это глобально для всех запросов POST, можно использовать этот код (взятый из полуответа Albireo):

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

Чтобы сделать это только для текущего поста, headers свойство объекта запроса необходимо изменить:

var req = {
method: 'POST',
url: 'http://example.com',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $httpParamSerializer(formDataObj)
};

$http(req);
57

Вы можете определить поведение глобально:

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

Так что вам не нужно каждый раз переопределять его:

$http.post("/handle/post", {
foo: "FOO",
bar: "BAR"}).success(function (data, status, headers, config) {
// TODO
}).error(function (data, status, headers, config) {
// TODO
});
24

В качестве обходного пути вы можете просто заставить код, получающий POST, отвечать на данные application / json. Для PHP я добавил код, приведенный ниже, что позволяет мне POST к нему в форме в кодировке или JSON.

//handles JSON posted arguments and stuffs them into $_POST
//angular's $http makes JSON posts (not normal "form encoded")
$content_type_args = explode(';', $_SERVER['CONTENT_TYPE']); //parse content_type string
if ($content_type_args[0] == 'application/json')
$_POST = json_decode(file_get_contents('php://input'),true);

//now continue to reference $_POST vars as usual
20

Эти ответы выглядят как безумное излишество, иногда просто лучше:

$http.post(loginUrl, "userName=" + encodeURIComponent(email) +
"&password=" + encodeURIComponent(password) +
"&grant_type=password").success(function (data) {
//...
16