简体   繁体   English

反应原生 Http 拦截器

[英]React Native Http Interceptor

Like most applications, I'm writing an application that requires a lot of similar logic in the http response/requests handlers.像大多数应用程序一样,我正在编写一个应用程序,它需要在 http 响应/请求处理程序中有很多类似的逻辑。 For instance, I have to always check for refresh tokens and save them to the AsyncStorage, or always set the headers to my AuthService headers, or even check for 404 to route to the same 404 error page.例如,我必须始终检查刷新令牌并将它们保存到 AsyncStorage,或者始终将标头设置为我的 AuthService 标头,甚至检查 404 以路由到相同的 404 错误页面。

I'm a big fan of the http interceptor in Angular;我非常喜欢 Angular 中的 http 拦截器; where you can define and register an http interceptor to (lack of a better term) intercept all http traffic and then run the combined, common logic.您可以在其中定义和注册一个 http 拦截器来(缺乏更好的术语)拦截所有 http 流量,然后运行组合的通用逻辑。

I have 2 main questions:我有两个主要问题:

  1. Since in React Native, we define these independent components, should we not be extracting common http logic in the first place in order to preserve the re-usability of the component?既然在 React Native 中,我们定义了这些独立的组件,难道我们应该首先提取常见的 http 逻辑,以保持组件的可重用性吗?
  2. If we don't want to duplicate code, is there a way in React Native (first) or Objective-C/Swift (second) to intercept http traffic and provide handlers for the requests?如果我们不想重复代码,在 React Native(第一个)或 Objective-C/Swift(第二个)中有没有办法拦截 http 流量并为请求提供处理程序?

Have you considered axios if you are trying to intercept only xhr?如果您只想拦截 xhr,您是否考虑过 axios? I am using axios interceptors - https://www.npmjs.com/package/axios and so far it seems to work.我正在使用 axios 拦截器 - https://www.npmjs.com/package/axios到目前为止它似乎工作。

Here is the sample code这是示例代码

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;

and then import this axiosInstance where ever you want to make xhr calls然后在你想要进行 xhr 调用的地方导入这个 axiosInstance

I'm not sure if I'm understanding this question correctly, or if your looking for more magic, but it sounds like you just want a wrapper to the XMLHttpRequest (or fetch API ).我不确定我是否正确理解了这个问题,或者您是否正在寻找更多魔法,但听起来您只是想要一个XMLHttpRequest (或fetch API )的包装器。 Wrap it in a class or a function and you can do whatever you want, whenever you want.将它包装在一个类或一个函数中,您可以随时随地做任何想做的事情。 Here's an example of an xhr wrapped in a promise:下面是一个包含在 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();
  });
}

Then you can just use that whenever you want to do HTTP calls...然后你就可以在你想要进行 HTTP 调用时使用它......

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

you can use react-native-easy-app that is easier to send http request and formulate interception request你可以使用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);
    }
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM