Мое угловое обещание неожиданно переходит к обратному вызову ошибки, почему?

У меня есть клиент, работающий на Angular + typescript, и я новичок в веб-разработке.

Мне нужно отправить почтовый запрос в php API (который я разработал). Запрос поступает на сервер правильно, и сервер заполняет тело ответа правильными данными (я проверял это сам, отлаживая сервер).

Проблема в том, что когда сервер отвечает, угловое обещание выполняет обратный вызов ошибки, а данные ответа пусты. Когда я проверяю отправленный запрос в браузере, он говорит, что на него ответили со статусом 200 OK, но у него пустое тело.

Я попытался вызвать ту же конечную точку API с теми же параметрами через надстройку Firefox Api-requester, и я получаю ответ с правильным телом... почему тогда мой клиент Angular не работает?

Следующий фрагмент кода соответствует моему контроллеру:

        vm.query = {
            'tx_filtre':'', 'idioma_filtre':'', 'tipus':'', 'id_dimfisica':'', 'tamPag':15, 'numPag':0
        };

        this.PropietatsService.getPropietats(vm.query)
            .then((response: ng.IHttpPromiseCallbackArg<string>) => {
                vm.objResult = JSON.parse(response.data);
                vm.propietats = vm.objResult.info;
                console.log('rebut', this.propietats);
            }, (response: ng.IHttpPromiseCallbackArg<string>) => {
                //always executes this error function, why????
                vm.objResult = JSON.parse(response.data);
            });

И это соответствующий код для службы:

getPropietats(query: any): ng.IPromise<ng.IHttpPromiseCallbackArg<string>> {
        var config = {
            headers : {
                'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
            }
        };
        return this.$http.post("http://localhost:8080/diccionaris/propietat/get",JSON.stringify(query),config);
    }

PS: также примечание: по какой-то причине мой сервер не может обработать запрос, если я установил для параметра «Тип контента» значение «application/json» в своем клиенте. Именно по этой причине я установил «application/x-www-form-urlencoded».

P.P.S: я знаю, что это больно, когда вы видите функцию get, вызываемую с запросом на публикацию, но я всего лишь выполнял приказы своего босса...

Заранее спасибо!


person Driond    schedule 30.11.2016    source источник
comment
Вы уверены, что получаете 200? Согласно документам, обратный вызов должен вызываться для любого кода состояния между 200-299   -  person Robin-Hoodie    schedule 30.11.2016
comment
Да, я проверил это в Chrome DevTools на вкладке «Сеть».   -  person Driond    schedule 30.11.2016


Ответы (3)


Вы устанавливаете «Content-Type»: «application/x-www-form-urlencoded; charset = utf-8;», но вы кодируете параметры запроса в JSON, а затем пытаетесь декодировать ответ как JSON. Попробуйте установить application/json или попробуйте удалить JSON.encode параметры запроса и отправить в сообщение методом query. Если это не помогает, запишите ошибку (в response) в обратном вызове ошибки и посмотрите на нее.

person Antonio    schedule 30.11.2016

Если сервер не может принять application/json, данные POST необходимо закодировать для application/x-www-form-urlencoded. Для этого используйте https://docs.angularjs.org/api/ng/service/$httpParamSerializer:

getPropietats(query: any): ng.IPromise<ng.IHttpPromiseCallbackArg<string>> {
    var config = {
        headers : {
            'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
        },
        transformRequest: $httpParamSerializer
    };
    return this.$http.post(url,query,config);
}
person georgeawg    schedule 30.11.2016

Наконец-то я нашел решение: это была проблема CORS.

Я запускал свой сервер и мой клиент в двух разных портах локального хоста, поэтому, хотя сервер обработал запрос (что не имеет для меня особого смысла), он не возвращал ответ, потому что клиенту не был разрешен доступ к серверу. . Чтобы справиться с этим, я добавил следующую строку в свой сервер index.php:

header('Access-Control-Allow-Origin: *');

И теперь он работает просто отлично.

person Driond    schedule 01.12.2016