Od jakiegoś czasu korzystam z przyjętego kodu odpowiedzi (kodu Felipe) i działa on świetnie (dzięki, Felipe!).
Jednak niedawno odkryłem, że ma problemy z pustymi obiektami lub tablicami. Na przykład podczas przesyłania tego obiektu:
{
A: 1,
B: {
a: [ ],
},
C: [ ],
D: "2"
}
PHP wydaje się wcale nie widzieć B i C. Otrzymuje to:
[
"A" => "1",
"B" => "2"
]
Spojrzenie na rzeczywiste żądanie w Chrome pokazuje:
A: 1
:
D: 2
Napisałem alternatywny fragment kodu. Wygląda na to, że działa dobrze z moimi przypadkami użycia, ale nie przetestowałem go dokładnie, więc używaj go ostrożnie.
Użyłem TypeScript, ponieważ lubię mocne pisanie, ale łatwo byłoby przekonwertować na czysty 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("&");
} ];
} ]);
Jest mniej wydajny niż kod Felipe, ale nie sądzę, żeby miało to duże znaczenie, ponieważ powinno być natychmiastowe w porównaniu do ogólnego obciążenia samego żądania HTTP.
Teraz PHP pokazuje:
[
"A" => "1",
"B" => [
"a" => ""
],
"C" => "",
"D" => "2"
]
O ile mi wiadomo, PHP nie może rozpoznać, że Ba i C są pustymi tablicami, ale przynajmniej pojawiają się klucze, co jest ważne, gdy istnieje kod, który opiera się na pewnej strukturze, nawet jeśli jest ona zasadniczo pusta.
Zauważ też, że konwertuje niezdefiniowane si null na puste ciągi.