在 React App 中使用 Axios 将响应数据下载为流 [英] Download Response Data as Stream w/ Axios in React App

查看:17
本文介绍了在 React App 中使用 Axios 将响应数据下载为流的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要通过将结果流式传输到 CSV 文件来从端点下载查询结果.这是为了支持一次通过浏览器发送大量 ResultSet.

I need to download query results from an endpoint by streaming results to a CSV file. This is in an effort to support enormous ResultSets being sent through the browser at one time.

有没有办法在 React 应用程序的上下文中使用 Axios 来实现这一点?

Is there a way to accomplish this using Axios in the context of a React App?

我见过 fetch() 并且知道它具有以下特点:

I have seen fetch() and know that it has the following characteristics:

  • 返回可读流
  • IE11 不支持
  • 不允许拦截请求
  • 响应的状态与请求本身有关,与 HTTP 状态无关
    • 这意味着接收错误的唯一方法是由于流提前结束而出现问题
    • 这肯定对我不起作用,因为我有与用户权限相关的自定义错误处理
    • returns ReadableStream
    • Is NOT supported by IE11
    • Does NOT allow for intercepting requests
    • The status of a response relates to the request itself, not the HTTP status
      • This means that the only way to receive an error would be to have something go wrong with the stream ending prematurely
      • This definitely won't work for me since I have custom error-handling related to user permissions

      除了 ReadableStream 响应类型之外,列出的其余特征都是不允许的.我需要支持 IE11 并允许拦截请求/读取 HTTP 状态以确定如何处理流量.

      Besides the ReadableStream response type, the rest of the characteristics listed are not permissible. I will need to support IE11 and allow for intercepting requests / reading the HTTP status to determine how to handle the traffic.

            // The promise returned by `fetch` rejects if the fetch was unable to make HTTP-request
            //  e.g. network problems, or there’s no such site.
            // Abnormal HTTP-statuses, such as 404 or 500 do not cause an error.
            const results = await fetch(`${URL}/data`, {
              method: 'post', // HTTP POST to send query to server
              headers: {
                Accept: 'application/json, text/plain, */*', // indicates which files we are able to understand
                'Content-Type': 'application/json', // indicates what the server actually sent
              },
              body: JSON.stringify(query), // server is expecting JSON
              credentials: 'include', // sends the JSESSIONID cookie with the address
            }).then(res => res.json()) // turn the ReadableStream response back into JSON
              .then((res) => {
                if (res.ok) {
                  // boolean, true if the HTTP status code is 200-299.
                  console.log('response.ok!');
                } else if (res.status === 401) {
                  throw Error(`You are not authenticated. Please login.`);
                } else if (res.status === 403) {
                  throw Error(`You are not authorized to access this data.`);
                } else {
                  throw Error(`Request rejected with status ${res.status}`);
                }
              })
              .catch((error) => {
                // catches error case and if fetch itself rejects
                error.response = {
                  status: 0,
                  statusText:
                    'Cannot connect. Please make sure you are connected to internet.',
                };
                throw error;
              });
      
            console.log(results);
      

      axios 的示例(非流媒体)

      Axios 实例

      import ...
      const Api = axios.create({
        baseURL: `${URL}`,
        withCredentials: true,
      });
      
      // attach interceptors to requests and responses
      // these are defined elsewhere and imported
      Api.interceptors.request.use((request) => requestHandler(request));
      Api.interceptors.response.use((response) => successHandler(response), (error) => errorHandler(error));
      
      export default Api;
      

      axios 请求

      const query = {"selections":{"TABLE_A":["COLUMN1"]},"filters":[{"predicates":[]}],"joins":[],"sorts":[],"limit":100,"offset":0}
      const response = await Api.post('/data', query);
      // further transformations to response to get formatted csv results required
      

      关于 Axios 的问题

      • 是否可以在 Axios 中拥有与 fetch 相同的 ReadableStream?
      • 仅当假设 Node 在仅服务器端设置中支持它时,才可以在 Axios 中进行流式传输吗?
        • this 等网站似乎在说使用 responseType: 'stream' 不是可以在浏览器中完成的事情,只能在 Node.js 中使用 fs
        • Questions about Axios

          • Is it possible to have a ReadableStream in Axios same as fetch?
          • Is streaming in Axios only possible when assuming that it will be supported by Node in a server-side only setting?
            • Sites like this appear to say that using responseType: 'stream' isn't something that can be done in the browser, only with Node.js using fs
            • 推荐答案

              当前支持从浏览器流式响应:

              Streaming a response from the browser is not currently supported :

              https://github.com/axios/axios/issues/479

              由于我们在浏览器中处理XMLHttpRequests,Axios 仅限于whatwg 设置的规范.:

              Since we're dealing with XMLHttpRequests in the browser, Axios is limited to the specification set by whatwg. :

              具体来说,这些是唯一支持的类型:

              Specifically, these are the only supported types :

              enum XMLHttpRequestResponseType {
                "",
                "arraybuffer",
                "blob",
                "document",
                "json",
                "text"
              };
              

              在 axios 中设置 responseType 时接受

              stream ,但这是误导.由于我们使用的是依赖于 XMLHttpRequests 的浏览器,因此适配器将是 xhr.js 隐式.HttpRequests 是在服务器端进行的,它将允许 axios 使用 http.js 适配器.然后你可以使用 stream 作为 Node.js 的 ResponseType.

              stream is accepted when setting a responseType in axios, but this is misleading. The adapter is going to be xhr.js implicitly since we are using the browser which relies on XMLHttpRequests. HttpRequests are made on the server-side and will allow axios to use the http.js adapter. THEN you can use stream as a ResponseType with Node.js.

              使用fetchAPI 似乎是将 ReadableStream 作为响应主体类型的唯一解决方案.

              Using the fetch API seems to be the only solution with a ReadableStream as a response body type.

              这篇关于在 React App 中使用 Axios 将响应数据下载为流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆