【问题标题】:Handling HTTP redirection status codes处理 HTTP 重定向状态码
【发布时间】:2019-08-26 03:25:03
【问题描述】:

我正在尝试处理 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)))
    );
};

有没有人知道任何更好的方法来处理这个问题,而我不必为所有新的史诗重复它?

【问题讨论】:

    标签: reactjs react-redux redux-observable


    【解决方案1】:

    ajax 操作包裹 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))
          )
        )
      )
    

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

    【讨论】:

    • 刚开始尝试这个(我知道,这是很久以前的事了),我收到错误:“你在预期流的地方提供了‘未定义’。你可以提供一个 Observable,Promise,数组,或可迭代。”有什么想法吗?
    • @fuudge 这通常是由于在其中一个运算符中忘记return 造成的。因此,当流继续时,下一个运算符将获得一个 undefined 值。我之前在 RxViz.com 上测试过上述内容,所以我不认为有问题(但总是有可能的)。如果您无法使其正常工作,请使用您正在尝试的更新代码发布一个新问题。我会尽量留意的。
    猜你喜欢
    • 1970-01-01
    • 2020-07-14
    • 2022-06-21
    • 2018-01-15
    • 2012-01-09
    • 2015-04-13
    • 2019-09-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多