Как сделать Angular 2 отправлять все запросы как application/x-www-form-urlencoded

У меня была аналогичная проблема с Angular 1, поэтому я понимаю, как реализовать, только мне не хватает последнего шага.

Как и в прошлый раз, парень, который сделал backend для нашего приложения, принимает запросы с типом application/x-www-form-urlencoded и точно так же, как Angular 1, поэтому Angular 2 отправляет их с типом application/json.

Что я сделал с ng1, так это то, что в config я изменил http-провайдер, чтобы запустить urlencoded над телом каждого запроса.

В ng2 я вижу, что есть https://angular.io/docs/ts/latest/api/http/BaseRequestOptions-class.html a BaseRequestOptions, который, как я полагаю, сделан именно для этой единственной документации, бит not there, поэтому я не уверен, как это реализовать правильно (я также новичок в TypeScript).

Как это сделать, чтобы каждый из моих post и других запросов отправлялся как urlencoded в конце (я также хочу, чтобы функция запускалась на теле так, чтобы она фактически была указана на urlencoded).

Кроме того: почему нет более простой опции для этого, так как теперь я вижу, что и ASP.Net, и Flask (так что, как я полагаю, многие другие) не поддерживают application\json по умолчанию?

EDIT: Я создал пользовательскую функцию, которую я использую для каждого объекта, который я отправляю в модуле POST, но я надеюсь, что есть более простое и более общее решение.

import { URLSearchParams } from 'angular2/http';

export function urlEncode(obj: Object): string {
    let urlSearchParams = new URLSearchParams();
    for (let key in obj) {
        urlSearchParams.append(key, obj[key]);
    }
    return urlSearchParams.toString();
}

а затем я использую его как

this.http.post('http://localhost:5000/user/auth/login', urlEncode(data))

Ответ 1

Попробуйте что-то вроде этого:

DefaultRequestOptions.ts

@Injectable()
export class DefaultRequestOptions extends BaseRequestOptions{
    headers:Headers = new Headers({
        'Content-Type': 'application/x-www-form-urlencoded'
    });
}

boot.ts

bootstrap(AppComponent,[
    HTTP_PROVIDERS,
    provide( RequestOptions, { useClass: DefaultRequestOptions } ),
    provide(Http, { useFactory:
        function(backend, defaultOptions) {
            return new Http(backend, defaultOptions); },
        deps: [XHRBackend, RequestOptions]})
]);

ВАЖНО: убедитесь, что вы еще не объявили HTTP_PROVIDERS в компоненте, где вы будете использовать объект Http, или он переопределит тот, который вы впрыскиваете в boot.ts.


Для другой функции вы можете просто добавить ее в любой объект @Injectable, добавить этот объект в конструктор своих компонентов, и вы можете называть его таким образом из любого компонента или можете попытаться расширить объект http angular и переопределить метод post, чтобы сделать это для каждого пост-запроса за кулисами.