2013-04-24 12 views
52

kątowa nie dodając odpowiednią opcję typu treści, próbowałem następujące polecenia:

$http({ 
    url: "http://localhost:8080/example/teste", 
    dataType: "json", 
    method: "POST", 
    headers: { 
     "Content-Type": "application/json" 
    } 
}).success(function(response){ 
    $scope.response = response; 
}).error(function(error){ 
    $scope.error = error; 
}); 

Powyższy kod generuje następujące żądanie http:

POST http://localhost:8080/example/teste HTTP/1.1 
Host: localhost:8080 
Connection: keep-alive 
Content-Length: 0 
Cache-Control: no-cache 
Pragma: no-cache 
Origin: http://localhost:8080 
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31 
Content-Type: application/xml 
Accept: application/json, text/plain, */* 
X-Requested-With: XMLHttpRequest 
Referer: http://localhost:8080/example/index 
Accept-Encoding: gzip,deflate,sdch 
Accept-Language: pt-BR,pt;q=0.8,en-US;q=0.6,en;q=0.4 
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3 
Cookie: JSESSIONID=C404CE2DA653136971DD1A3C3EB3725B 

Jak widać, zamiast "application/json", typem treści jest "application/xml". Czy coś mi umyka ?

Odpowiedz

79

Musisz załączyć treść z żądaniem. Angular w inny sposób usuwa nagłówek treści.

Dodaj data: '' do argumentu do $http.

+3

ale co jeśli chcę wysłać obiekt danych? Pracuję z obsługą standardu HTTP ASP.NET i z jakiegoś powodu 'context.Request.Params [" formData "]' nie działa, ale post Stackoverflow doprowadził mnie do użycia 'string json = new StreamReader (context. Request.InputStream) .ReadToEnd(); 'który działa, ale nie odczuwam ulgi w używaniu go, ponieważ wolałbym uzyskać dostęp do wartości parametru zgłoszonego żądania według nazwy. –

+1

Boże, to jest ratownik! Czy jest to domyślne zachowanie protokołu HTTP lub zachowanie Angular $ http? – jchnxu

+0

Dla każdego, kto używa [Restangular] (https://github.com/mgonto/restangular), oto przykładowy sposób wdrożenia tego rozwiązania: https://gist.github.com/sscovil/3bd0da1d98397213df54 –

26
$http({ 
    url: 'http://localhost:8080/example/teste', 
    dataType: 'json', 
    method: 'POST', 
    data: '', 
    headers: { 
     "Content-Type": "application/json" 
    } 

}).success(function(response){ 
    $scope.response = response; 
}).error(function(error){ 
    $scope.error = error; 
}); 

Spróbuj tego.

+2

Obawiam się, że nie działa w Angular 1.3.14, "Content-Type" jest usuwany, jeśli nie ma "danych".Pusty parametr "data" rozwiązuje problem ... – IProblemFactory

+0

Bardzo dziwne! nawet dla żądania GET również musiałem podać dane: pole. choć wszyscy wiemy, że GET nie powinien mieć ciała! jaki jest powód, dla którego angularjs usuwa aplikację/nagłówek typu zawartości, gdy nie są dostarczane żadne dane? – agpt

1

Świetnie! Powyższe rozwiązanie sprawdziło się u mnie. Miał ten sam problem z połączeniem GET.

method: 'GET', 
data: '', 
headers: { 
     "Content-Type": "application/json" 
} 
+1

Dodaj trochę formatowania do fragmentów kodu. I wyjaśnij sobie lepiej, aby uniknąć głosowania w dół – simonmorley

+0

Żądanie GET nie może mieć ciała (http://stackoverflow.com/a/983458/2416700), więc Content-Type nie ma znaczenia w tym przypadku – Evgeny

+0

jest prawdą, że żądanie GET nie może mieć treści , ale dziwne, gdy podaje się dane jako pusty ciąg, wtedy brany jest tylko typ zawartości, inne mądre angulary są usuwane z tego nagłówka. !! – agpt

3
  $http({ 
       method: 'GET', 
       url:'/http://localhost:8080/example/test' + toto, 
       data: '', 
       headers: { 
        'Content-Type': 'application/json' 
       } 
      }).then(
       function(response) { 
        return response.data; 
       }, 
       function(errResponse) { 
        console.error('Error !!'); 
        return $q.reject(errResponse); 
       } 
0

Wystarczy pokazać przykład jak dynamicznie dodać "Content-type" nagłówek na każde żądanie POST. W tym przypadku przekazuję parametry POST jako ciąg zapytania, który jest wykonywany za pomocą transformRequest. W tym przypadku jego wartość to application/x-www-form-urlencoded.

// set Content-Type for POST requests 
angular.module('myApp').run(basicAuth); 
function basicAuth($http) { 
    $http.defaults.headers.post = {'Content-Type': 'application/x-www-form-urlencoded'}; 
} 

Następnie z kolektora w metodzie żądanie zanim zwróci obiekt config

// if header['Content-type'] is a POST then add data 
'request': function (config) { 
    if (
    angular.isDefined(config.headers['Content-Type']) 
    && !angular.isDefined(config.data) 
) { 
    config.data = ''; 
    } 
    return config; 
} 
1

W przypadku, jest to przydatne dla każdego. Dla angularjs 1.5x Chciałem ustawić CSRF dla wszystkich żądań i znalazłem, że kiedy to zrobił:

$httpProvider.defaults.headers.get = { 'CSRF-Token': afToken }; 
$httpProvider.defaults.headers.put = { 'CSRF-Token': afToken }; 
$httpProvider.defaults.headers.post = { 'CSRF-Token': afToken }; 

kątowa usunięty typ zawartości, więc musiałem dodać to:

$httpProvider.defaults.headers.common = { "Content-Type": "application/json"}; 

Inaczej dostać błąd typu 415 mediów.

Więc robię to skonfigurować mojej aplikacji dla wszystkich żądań:

angular.module("myapp.maintenance", []) 
    .controller('maintenanceCtrl', MaintenanceCtrl) 
    .directive('convertToNumber', ConvertToNumber) 
    .config(configure); 

MaintenanceCtrl.$inject = ["$scope", "$http", "$sce", "$window", "$document", "$timeout", "$filter", 'alertService']; 
configure.$inject = ["$httpProvider"]; 

// configure the header tokens for CSRF for http operations in this module 
function configure($httpProvider) { 

    const afToken = angular.element('input[id="__AntiForgeryToken"]').attr('value'); 

    $httpProvider.defaults.headers.get = { 'CSRF-Token': afToken }; // only added for GET 
    $httpProvider.defaults.headers.put = { 'CSRF-Token': afToken }; // added for PUT 
    $httpProvider.defaults.headers.post = { 'CSRF-Token': afToken }; // added for POST 

    // for some reason if we do the above we have to set the default content type for all 
    // looks like angular clears it when we add our own headers 
    $httpProvider.defaults.headers.common = { "Content-Type": "application/json" }; 

} 
Powiązane problemy