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

问题描述

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

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 App的上下文中使用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:

  • 返回ReadableStream
  • 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实例

      Example with axios (not streaming)

      Axios instance

      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中将ReadableStreamfetch相同?
      • 仅当假定节点将在仅服务器端设置中支持Axios时,才可以在Axios中进行流传输吗?
        • 似乎说使用responseType: 'stream'不能在浏览器中完成,只有使用fs
        • 的Node.js才能完成.

          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. :

              • https://xhr.spec.whatwg.org/#interface-xmlhttprequest
              • https://github.com/whatwg/xhr

              具体来说,以下是唯一受支持的类型:

              Specifically, these are the only supported types :

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

              在axios中设置responseType时,可以接受

              stream,但这会引起误解.适配器将隐式地为xhr.js,因为我们使用的是依赖于XMLHttpRequests的浏览器. HttpRequest在服务器端进行,将允许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.

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

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

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

07-22 13:51