Как правильно сделать запрос Observable.ajax.post в RXJS5

Я использую redux-observable с rxjs 5.5, и я пытаюсь сделать базовый запрос POST ajax на экспресс-сервер node.

Кажется, я не могу найти соответствующую документацию или актуальные рабочие примеры для Observable.ajax. Какое бы решение ни предлагалось, оно выдает некоторую ошибку, несмотря на то, что кажется правильной подписью в соответствии с фактическим API.

Мой текущий фрагмент кода с использованием (redux-observable и rxjs 5.5: выглядит следующим образом:

const loginEpic = (actions) =>  { 

    const opts = credentials => {
        const { username, password } = credentials;
        return {
            url: 'http://localhost:3001/login',
            body:{ username, password },
            headers: {  'Content-Type': 'application/json; charset=utf-8' },
        };       
    };

     return actions.ofType(ActionTypes.LOGIN_REQUESTED)
        .switchMap(({credentials}) => {
            const { url, body, headers } = opts(credentials)
            return Observable.ajax.post(url, body, headers)
            .map(loginResponse => 
                loginResponse.status===200
                    ? loginResolvedAction(loginResponse.response)
                    : loginFailedAction(loginResponse.response))})
}

Это энная попытка заставить это работать, но безрезультатно. Первая проблема заключается в том, что я хотел бы установить для свойства crossDomain значение true, поскольку его значение по умолчанию равно false, однако, похоже, нигде не устанавливается такое свойство (несмотря на то, что Chrome Dev Tools показывает, что оно есть.

Вот ошибка:

Failed to load http://localhost:3001/login: Request header field X-Requested-With is not allowed by Access-Control-Allow-Headers in preflight response.

Я использую простой экспресс-сервер на задней панели, который просто возвращает базовый объект JSON, когда URL-адрес попадает в сообщение. Однако эта конечная точка не попадает в текущий запрос Observable.ajax.post выше.

У меня есть плагин Chrome, который позволяет CORS, и использование других библиотек, таких как Axios, похоже, работает. Тем не менее, я предпочитаю использовать Observables и redux-observable, а rxjs — отличные библиотеки, спасибо авторам, но я не могу разобраться в проблеме с ajax. Кто-нибудь может помочь?


person Community    schedule 05.12.2017    source источник
comment
Вы можете использовать redux-observable с обещаниями, просто преобразуйте свое обещание в наблюдаемое, используя Observable.fromPromise   -  person Robert Farley    schedule 05.12.2017


Ответы (1)


Хм, кажется, я преодолел проблему, хотя я не вижу, как это решение на самом деле исправило ее, поскольку оно не согласовано с API. Вот мое решение, если у кого-то есть подобные проблемы.

const reportsEpic = (actions) => {

    const requestSettings = token => ({
        url:`http://localhost:3001/testReports/${token}`, 
        crossDomain: true,
        contentType: "application/json; charset=utf-8",
        responseType:'json',
    })

    return actions.ofType(ActionTypes.REPORTS_REQUESTED)
        .switchMap(({token}) => 
            Observable.ajax(requestSettings(token))
            .map(reportsResponse => 
                reportsResolvedAction(reportsResponse.response)));
}

Мое замешательство возникает из-за API, который предоставляет Observable.ajax.post как:

(method) AjaxCreationMethod.post(url: string, body?: any, headers?: Object): Observable<AjaxResponse>

Однако использование ajax без определенного почтового метода задается как:

let Observable<T>.ajax: AjaxCreationMethod(urlOrRequest: string | AjaxRequest) => Observable<AjaxResponse>

Передача «POST» в качестве параметра объекта запроса. Эти две подписи кажутся запутанными. Зачем использовать ajax.post(), если он терпит неудачу там, где ajax() нет?

У кого-нибудь есть понимание этого?

person Community    schedule 05.12.2017
comment
ajax.post() создает объект AjaxRequest из своих аргументов, где значение по умолчанию для crossDomain равно false. ajax() позволяет вам определить фактический AjaxRequest, поэтому вы можете установить crossDomain. Методы post(), get() и т. д. удобны, поэтому использование ajax() напрямую согласуется с API и полезно для вашего варианта использования. - person Robert Farley; 05.12.2017