Обработка кодов состояния перенаправления HTTP - PullRequest
1 голос
/ 04 апреля 2019

Я пытаюсь обработать коды состояния перенаправления HTTP (например, перенаправление 302, когда время сеанса истекло), и я не знаю, существует ли универсальный способ обработки определенных кодов ответов с использованием избыточного-наблюдаемого? У меня сейчас проблема в том, что браузер следует местоположению, указанному в ответе 302, и я могу только нажать на последующие 200 ответов для страницы входа. Теперь у меня есть хак, когда я обнаруживаю слово «логин» в URL-адресе ответа и перенаправляю на страницу входа с помощью объекта window.location. Я должен делать это в каждом эпосе.

Вот что у меня есть:

    export const getData = (action$) => {
    return action$.pipe(
        ofType(GET_DATA_REQUEST),
        mergeMap(action => {
            return ajax(options).pipe(
                map((response) => response.originalEvent.currentTarget.responseURL.endsWith('login') ? window.location.href = 'login' : getDataSuccess(response.response)),
                catchError(error => of(getDataFailure(error)))
            );
        }),
        catchError(error => of(getDataFailure(error)))
    );
};

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

1 Ответ

1 голос
/ 04 апреля 2019

Операции ajax переносят XMLHttpRequest, а XMLHttpRequest автоматически следует за перенаправлениями. Хотя перенаправление не может быть предотвращено, оно может быть обнаружено. Вот еще один пример обнаружения перенаправления:

export const getData = action$ =>
  action$.pipe(
    ofType(GET_DATA_REQUEST),
    mergeMap(action =>
      ajax(options).pipe(
        mergeMap(response => {
          // Navigate to login if the request was successful but redirected
          if (response.status >= 200 && response.status < 300 && response.responseURL !== options.url) {
            window.location.href = 'login'
            return empty()
          }

          return of(getDataSuccess(response.response))
        })
      )
    )
  )

Если вы хотите повторно использовать эту логику в нескольких эпосах, просто экспортируйте ее как функцию многократного использования:

export const ajaxWithLoginRedirect = options =>
  ajax(options).pipe(
    mergeMap(response => {
      // Navigate to login if the request was successful but redirected
      if (response.status >= 200 && response.status < 300 && response.responseURL !== options.url) {
        window.location.href = 'login'
        return empty()
      }

      // Return the raw response
      return of(response)
    })
  )

export const getData = action$ =>
  action$.pipe(
    ofType(GET_DATA_REQUEST),
    mergeMap(action =>
      ajaxWithLoginRedirect(options).pipe(
        // This is only called if we did not redirect
        map(response => getDataSuccess(response.response))
      )
    )
  )

Обратите внимание, что fetch API поддерживает поддержку обработки перенаправлений вручную (объект ответа, который вы получите, будет иметь код состояния 3xx). Существует ряд компромиссов между XMLHttpRequest и fetch, поэтому я хотел бы выяснить, что если , а не , то в вашем приложении предпочтительнее автоматически выполнять следующие перенаправления.

...