AngularJS-любой способ для $ http.post для отправки параметров запроса вместо JSON?
у меня есть старый код, который делает запрос AJAX POST через метод post jQuery и выглядит так:
$.post("/foo/bar", requestData,
function(responseData)
{
//do stuff with response
}
requestData
- это просто объект javascript с некоторыми базовыми строковыми свойствами.
Я в процессе перемещения наших вещей, чтобы использовать Angular, и я хочу заменить этот вызов $http.должность. Я придумал следующее:--10-->
$http.post("/foo/bar", requestData).success(
function(responseData) {
//do stuff with response
}
});
когда я это сделал, я получил ответ об ошибке 500 от сервера. С помощью Firebug, я обнаружил, что это отправило тело запроса следующим образом:
{"param1":"value1","param2":"value2","param3":"value3"}
успешный jQuery $.post
посылает тело так:
param1=value1¶m2=value2¶m3=value3
конечная точка, на которую я нажимаю, ожидает параметры запроса, а не JSON. Итак, мой вопрос в том, есть ли в любом случае сказать $http.post
отправить объект javascript в качестве параметров запроса вместо JSON? Да, я знаю, что мог бы построить строку сам из объекта, но я хочу знать, предоставляет ли Angular что-нибудь для этого из коробка.
13 ответов
Я думаю params
config параметр не будет работать здесь, так как он добавляет строку в url вместо тела, но добавить к тому, что Infeligo предложил здесь, является примером глобального переопределения преобразования по умолчанию (используя jQuery параметр в качестве примера для преобразования данных в строку param).
настройка глобальной функции transformRequest:
var app = angular.module('myApp');
app.config(function ($httpProvider) {
$httpProvider.defaults.transformRequest = function(data){
if (data === undefined) {
return data;
}
return $.param(data);
}
});
таким образом, все вызовы $http.post автоматически преобразует тело в то же самое формат param, используемый jQuery $.post
звонок.
Примечание Вы также можете установить заголовок Content-Type для каждого вызова или глобально, как это:
$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
пример неглобального transformRequest за вызов:
var transform = function(data){
return $.param(data);
}
$http.post("/foo/bar", requestData, {
headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
transformRequest: transform
}).success(function(responseData) {
//do stuff with response
});
при использовании угловые >= 1.4, вот самое чистое решение, которое я нашел, которое не зависит от чего-либо пользовательского или внешнего:
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
заголовок Content-Type, как обычно ожидается, с запросами POST на конечных точках.
из документации AngularJS:
params - {объект.} – Отображение строк или объектов, которые будут обращены ?key1=value1 & key2=value2 после url. если значение не является строкой, это будет JSONified.
Итак, укажите строку в качестве параметров. Если вы этого не хотите, используйте преобразования. Опять же, из документации:
чтобы переопределить эти преобразования локально, укажите функции преобразования как свойства transformRequest и / или transformResponse конфигурации объект. Чтобы глобально переопределить преобразования по умолчанию, переопределите $ httpProvider.по умолчанию.transformRequest и $ httpProvider.по умолчанию.свойства transformResponse из $ httpProvider.
смотрите документация для получения более подробной информации.
используйте jQuery $.param
функция для сериализации данных JSON в requestData.
короче говоря, используя аналогичный код, как ваш:
$http.post("/foo/bar",
$.param(requestData),
{
headers:
{
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
}
).success(
function(responseData) {
//do stuff with response
}
});
для использования этого вы должны включить jQuery на свою страницу вместе с AngularJS.
обратите внимание, что с Angular 1.4 вы можете сериализовать данные формы без использования jQuery.
в приложение.js:
module.run(function($http, $httpParamSerializerJQLike) {
$http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
});
затем в вашем контроллере:
$http({
method: 'POST',
url: myUrl',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: myData
});
Это может быть немного взломать, но я избежал проблемы и преобразовал JSON в массив сообщений PHP на стороне сервера:
$_POST = json_decode(file_get_contents('php://input'), true);
У меня также есть проблемы с настройкой пользовательской аутентификации http, потому что $resource кэширует запрос.
чтобы заставить его работать, вы должны перезаписать существующие заголовки, сделав это
var transformRequest = function(data, headersGetter){
var headers = headersGetter();
headers['Authorization'] = 'WSSE profile="UsernameToken"';
headers['X-WSSE'] = 'UsernameToken ' + nonce
headers['Content-Type'] = 'application/json';
};
return $resource(
url,
{
},
{
query: {
method: 'POST',
url: apiURL + '/profile',
transformRequest: transformRequest,
params: {userId: '@userId'}
},
}
);
надеюсь, я смог кому-то помочь. Мне потребовалось 3 дня, чтобы это понять.
изменить заголовки по умолчанию:
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";
тогда используйте jQuery $.param
способ:
var payload = $.param({key: value});
$http.post(targetURL, payload);
.controller('pieChartController', ['$scope', '$http', '$httpParamSerializerJQLike', function($scope, $http, $httpParamSerializerJQLike) {
var data = {
TimeStamp : "2016-04-25 12:50:00"
};
$http({
method: 'POST',
url: 'serverutilizationreport',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
data: $httpParamSerializerJQLike(data),
}).success(function () {});
}
]);
Быстрая настройка - для тех из вас, у кого возникли проблемы с глобальной конфигурацией функции transformRequest, вот фрагмент, который я использую, чтобы избавиться от Cannot read property 'jquery' of undefined
ошибка:
$httpProvider.defaults.transformRequest = function(data) {
return data != undefined ? $.param(data) : null;
}
вы также можете решить эту проблему без изменения кода на сервере, изменив заголовок в $http.post
и $_POST
обычным способом. Объяснено здесь: http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/
Я нашел много раз проблемное поведение этого целого. Я использовал его из express (без типизаций) и bodyParser (с типизациями DT~body-parser).
Я не пытался загрузить файл, а просто интерпретировать JSON, заданный в строке post.
на request.body
был просто пустым json ({}
).
после долгого расследования, наконец, это сработало для меня:
import { json } from 'body-parser';
...
app.use(json()); <-- should be defined before the first POST handler!
это может быть также важно, чтобы дать application/json
введите содержимое строка запроса со стороны клиента.
синтаксис для AngularJS v1.4.8 + (v1.5.0)
$http.post(url, data, config)
.then(
function (response) {
// success callback
},
function (response) {
// failure callback
}
);
например:
var url = "http://example.com";
var data = {
"param1": "value1",
"param2": "value2",
"param3": "value3"
};
var config = {
headers: {
'Content-Type': "application/json"
}
};
$http.post(url, data, config)
.then(
function (response) {
// success callback
},
function (response) {
// failure callback
}
);