【问题标题】:React Native Http Interceptor反应本机 Http 拦截器
【发布时间】:2015-07-08 20:08:22
【问题描述】:

像大多数应用程序一样,我正在编写一个应用程序,它需要在 http 响应/请求处理程序中使用很多类似的逻辑。例如,我必须始终检查刷新令牌并将它们保存到 AsyncStorage,或者始终将标头设置为我的 AuthService 标头,甚至检查 404 以路由到相同的 404 错误页面。

我是 Angular 中的 http 拦截器的忠实粉丝;您可以在其中定义和注册一个 http 拦截器(没有更好的术语)拦截所有 http 流量,然后运行组合的通用逻辑。

我有两个主要问题:

  1. 由于在 React Native 中,我们定义了这些独立的组件,我们是否应该首先提取通用的 http 逻辑以保持组件的可重用性?
  2. 如果我们不想重复代码,React Native(第一个)或 Objective-C/Swift(第二个)有没有办法拦截 http 流量并为请求提供处理程序?

【问题讨论】:

    标签: javascript swift reactjs react-native


    【解决方案1】:

    如果你只想拦截 xhr,你考虑过 axios 吗? 我正在使用 axios 拦截器 - https://www.npmjs.com/package/axios 到目前为止,它似乎有效。

    这里是示例代码

    import axios from 'axios';
    import promise from 'promise';
    
    // Add a request interceptor 
    var axiosInstance = axios.create();
    
    axiosInstance.interceptors.request.use(function (config) {
      // Do something before request is sent 
      //If the header does not contain the token and the url not public, redirect to login  
      var accessToken = getAccessTokenFromCookies();
    
      //if token is found add it to the header
      if (accessToken) {
        if (config.method !== 'OPTIONS') {
              config.headers.authorization = accessToken;
            }
      }
      return config;
    }, function (error) {
       // Do something with request error 
       return promise.reject(error);
    });
    
    export default axiosInstance;
    

    然后将这个 axiosInstance 导入到任何你想进行 xhr 调用的地方

    【讨论】:

    • 打电话时如何导入axiosInstance?我可以提出请求,但 axiosInstance 回调没有被触发
    • @karan 您需要使用新实例。 - 从 '../gateway/axiosInstance' 导入 axiosInstance 导出函数 processBooks(userName, age) { var booksUrl = '/service/process-books?name=' + encodeURIComponent(userName) + '&age=' + encodeURIComponent(age) ;请求 = axiosInstance.post(booksUrl);退货请求; }
    • 您是将 accessToken 存储在AsyncStorage 还是其他地方?
    • @AmitTeli 你知道如何为来自 react native 应用程序和 webview 的各种 http 调用制作拦截器
    • 让我感到困惑的是,错误回调并没有像我最初想象的那样被调用响应错误(401 等)。您需要为此创建一个单独的响应拦截器 (axiosInstance.interceptors.response.use(...))。
    【解决方案2】:

    我不确定我是否正确理解了这个问题,或者您是否正在寻找更多魔法,但听起来您只是想要XMLHttpRequest(或fetch API)的包装。将它包装在一个类或一个函数中,你可以随时随地做任何你想做的事情。下面是一个包装在 Promise 中的 xhr 示例:

    function request(url, method = "GET") {
      const xhr = new XMLHttpRequest();
    
      // Do whatever you want to the xhr... add headers etc
    
      return new Promise((res, rej) => {
        xhr.open(method, url);
        xhr.onload = () => {
          // Do whatever you want on load...
          if (xhr.status !== 200) {
            return rej("Upload failed. Response code:" + xhr.status);
          }
          return res(xhr.responseText);
        };
        xhr.send();
      });
    }
    

    然后,您可以在任何时候使用它来进行 HTTP 调用...

    request("http://blah.com")
      .then(data => console.log(`got data: ${data}`))
      .catch(e => console.error(`error: ${e}`));
    

    【讨论】:

    • 是的,这就是我最终要走的路。我一直在寻找能够让我在导航器堆栈上推送东西的魔法(当用户无法访问互联网时,将此组件推送到堆栈上,或者总是在 401 等时重定向到登录。)。
    【解决方案3】:

    你可以使用react-native-easy-app更方便的发送http请求和制定拦截请求

    import {XHttpConfig} from 'react-native-easy-app';
    
    XHttpConfig.initHttpLogOn(true) // Print the Http request log or not
                .initBaseUrl(ApiCredit.baseUrl) // BaseUrl
                .initContentType(RFApiConst.CONTENT_TYPE_URLENCODED)
                .initHeaderSetFunc((headers, request) => {
                   // Set the public header parameter here
                })
                .initParamSetFunc((params, request) => {
                   // Set the public params parameter here
                })
                .initParseDataFunc((result, request, callback) => {
                   let {success, json, response, message, status} = result;
                   // Specifies the specific data parsing method for the current app
            });
    
    * Synchronous request
    const response = await XHttp().url(url).execute('GET');
    const {success, json, message, status} = response;
    
    
    * Asynchronous requests
    XHttp().url(url).get((success, json, message, status)=>{
        if (success){
           this.setState({content: JSON.stringify(json)});
        } else {
           showToast(msg);
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-13
      • 1970-01-01
      • 2014-05-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 2017-11-07
      相关资源
      最近更新 更多