RxJs Как установить заголовки запросов по умолчанию?

Не уверен, есть ли способ установить заголовки запросов по умолчанию в rxjs, как мы делаем с axios js as-

axios.defaults.headers.common['Authorization'] = 'c7b9392955ce63b38cf0901b7e523efbf7613001526117c79376122b7be2a9519d49c5ff5de1e217db93beae2f2033e9';

Вот мой эпический код, где я хочу установить заголовки запроса -

export default function epicFetchProducts(action$, store) {
    return action$.ofType(FETCH_PRODUCTS_REQUEST)
    .mergeMap(action =>
        ajax.get(`http://localhost/products?${action.q}`)
      .map(response => doFetchProductsFulfilled(response))
    );
}

Пожалуйста помоги.

2 ответа

Я использую наблюдаемую избыточность, но это относится к rxjs; может быть, следующий ответ слишком перегружен, но мне нужно было динамически получать заголовки в зависимости от определенных факторов, не влияя на юнит-тестирование (что-то не связанное с моими эпосами), и не изменяя синтаксис ajax.get / ajax.post и т.д., вот что я нашел:

ES6 имеет поддержку прокси, и после прочтения и улучшения решения я использую функцию высокого порядка, чтобы создать прокси в исходном объекте rxjs/ajax и вернуть проксифицированный объект; ниже мой код:

Примечание: я использую машинопись, но вы можете перенести ее на обычный ES6.

AjaxUtils.ts

export interface AjaxGetHeadersFn {
    (): Object;
}

// the function names we will proxy
const getHeadersPos = (ajaxMethod: string): number => {
    switch (ajaxMethod) {
        case 'get':
        case 'getJSON':
        case 'delete':
            return 1;
        case 'patch':
        case 'post':
        case 'put':
            return 2;
        default:
            return -1;
    }
};

export const ajaxProxy = (getHeadersFn: AjaxGetHeadersFn) =>
    <TObject extends object>(obj: TObject): TObject => {
        return new Proxy(obj, {
            get(target: TObject, propKey: PropertyKey) {
                const origProp = target[propKey];
                const headersPos = getHeadersPos(propKey as string);

                if (headersPos === -1 || typeof origProp !== 'function') {
                    return origProp;
                }

                return function (...args: Array<object>) {
                    args[headersPos] = { ...args[headersPos], ...getHeadersFn() };
                    // @ts-ignore
                    return origProp.apply(this, args);
                };
            }
        });
    };

Вы используете это так:

ConfigureAjax.ts

import { ajax as Ajax } from 'rxjs/ajax'; // you rename it

// this is the function to get the headers dynamically
// anything, a function, a service etc.
const getHeadersFn: AjaxGetHeadersFn = () => ({ 'Bearer': 'BLABLABLA' });

const ajax = ajaxProxy(getHeadersFn)(Ajax); // proxified object
export default ajax;

В любое место вашего приложения вы импортируете ajax из ConfigureAjax.ts и используете его как обычно.

Если вы используете redux-observable, вы настраиваете эпики следующим образом (добавление ajax-объекта в качестве зависимости подробнее здесь):

ConfigureStore.ts

import ajax from './ConfigureAjax.ts'

const rootEpic = combineEpics(
    fetchUserEpic
)({ ajax });

UserEpics.ts

// the same sintax ajax.getJSON, decoupled and
// under the covers with dynamically injected headers
const fetchUserEpic = (action$, state$, { ajax }) => action$.pipe(
  ofType('FETCH_USER'),
  mergeMap(({ payload }) => ajax.getJSON(`/api/users/${payload}`).pipe(
    map(response => ({
      type: 'FETCH_USER_FULFILLED',
      payload: response
    }))
  )
);

Надеюсь, это поможет людям, которые ищут то же самое:D

Невозможно установить заголовки по умолчанию для всех запросов ajax, используя утилиты RxJS ajax.

Однако вы можете предоставить заголовки в каждом вызове или создать свою собственную простую оболочку, которая предоставляет их по умолчанию.

Utils/ajax.js

const defaultHeaders = {
  Authorization: 'c7b9392955ce63b38cf090...etc'
};

export const get = (url, headers) =>
  ajax.get(url, Object.assign({}, defaultHeaders, headers));

мой-example.js

import * as ajax from './utils/ajax';

// Usage is the same, but now with defaults
ajax.get(`http://localhost/products?${action.q}`;)
Другие вопросы по тегам