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}`;)