问题描述
我需要通过将结果流式传输到 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
- Is it possible to have a
ReadableStream
in Axios same asfetch
? - 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 usingfs
推荐答案
当前不支持从浏览器流式响应:
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 bywhatwg
. :具体来说,这些是唯一支持的类型:
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 aresponseType
in axios, but this is misleading. The adapter is going to bexhr.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 thehttp.js
adapter. THEN you can usestream
as a ResponseType with Node.js.使用
fetch
API 似乎是将ReadableStream
作为响应主体类型的唯一解决方案.Using the
fetch
API seems to be the only solution with aReadableStream
as a response body type.这篇关于在 React App 中使用 Axios 将响应数据下载为流的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
- Sites like this appear to say that using
Questions about Axios
- this 等网站似乎在说使用