【问题标题】:How to handle stream in Angular HTTPClient如何在 Angular HTTPClient 中处理流
【发布时间】:2020-09-19 00:13:19
【问题描述】:

我有一个将数据块写入响应的后端(Spring Boot)API。我正在尝试从我的 Angular 代码中读取它。我期望的是从服务器接收大块数据。但是,httpClientget 方法在从服务器检索到所有数据之前不会返回任何内容。我已经给出了下面的代码

Spring Boot 代码

@GetMapping(value = "/stream", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE)
public ResponseEntity<StreamingResponseBody> fetchData(@RequestParam String path) {
    try {
        Pair<InputStream, Long> streamAndLen = CommonUtils.getTestStream();
        InputStream stream = streamAndLen.getKey();
        StreamingResponseBody resp =  outputStream -> {
            CommonUtils.copy(stream, outputStream);
            stream.close();
        };
        return ResponseEntity.ok()
            .header(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, HttpHeaders.CONTENT_TYPE)
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE)
            .contentLength(streamAndLen.getValue())
            .contentType(MediaType.APPLICATION_OCTET_STREAM)
            .body(resp);
    } catch (Exception e) {
        throw new RuntimeException("Could not get the data for the requested file", e);
    }
}

==============CommonUtils==================

public static Pair<InputStream, Long> getTestStream() {
    File file = new File("file_path_in_system");
    try {
        return new Pair<>(new FileInputStream(file), file.length());
    } catch (FileNotFoundException e) {
        e.printStackTrace();
        throw new RuntimeException("File " + file.getAbsolutePath() + " is not found.", e);
    }
}

public static void copy(InputStream stream, OutputStream outputStream) {
    try {
        int buffSize = 1024 * 4;
        byte[] data = new byte[buffSize];
        int length = -1;
        while ((length = stream.read(data)) != -1) {
            outputStream.write(data, 0, length);
            outputStream.flush();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Pair 只是一个键和值 POJO。

角度 sn-p

let headers = new HttpHeaders().set('Accept', 'application/octet-stream');
this.http.get(env.streamURL + '?path=' + this.filePath, { headers, observe: 'body', reportProgress: true, responseType: 'blob' })
  .pipe(
    map(res => {
      console.log(res);
    })
  )
  .subscribe(
    (res: any) => {
      console.log('res = ' + res);
    }
  );

我想在我的 Angular 应用程序中获取数据块(在每次从服务器调用 flush 之后),而不是等待所有块。有没有办法实现?

【问题讨论】:

    标签: angular stream httpclient chunks


    【解决方案1】:

    如果你想从服务器获取块,我会建议 HTML 5 API,即 SSE

    您可以阅读有关它的更多信息
    https://www.w3schools.com/html/html5_serversentevents.asp

    另外,您可以在以下链接中查看演示
    https://www.w3schools.com/html/tryit.asp?filename=tryhtml5_sse

    【讨论】:

    • 感谢您的意见。我正在寻找可以传递身份验证凭据或令牌的东西。当我之前尝试使用 SSE 时,我发现 EventSource 不支持身份验证。
    • 您可以将 EventSourceInit 对象传递给 EventSource 构造函数,例如new EventSource(url, { withCredentials: true })stackoverflow.com/questions/16266493/…
    • 使用 SSE 是个坏主意,因为浏览器将它们限制为最大连接数 5 左右
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-19
    • 2018-06-26
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多