首页 > 解决方案 > 处理 HTTP 重定向状态码

问题描述

我正在尝试处理 HTTP 重定向状态代码(例如会话超时时的 302 重定向),但我不知道是否有一种通用的方法可以使用 redux-observable 来处理特定的响应代码?我现在遇到的问题是浏览器遵循 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)))
    );
};

有谁知道处理这个问题的更好方法,我不必为所有新的史诗重复它?

标签: reactjsreact-reduxredux-observable

解决方案


ajax操作 wrap ,XMLHttpRequestXMLHttpRequest自动遵循重定向。虽然无法阻止重定向,但可以检测到它。这是检测重定向的另一个示例:

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))
      )
    )
  )

请注意,fetchAPI 确实支持手动处理重定向(您返回的响应对象将具有 3xx 状态代码)。XMLHttpRequest和之间有许多权衡fetch,所以我会研究,如果自动跟踪重定向,在您的应用程序中更可取。


推荐阅读