使用提取时无法获取ReadableStream

时间:2020-08-14 10:49:27

标签: javascript reactjs blob fetch-api webapi

我开始基于Web API / ReactJS开发新的Web应用程序,我有具有以下签名的api方法:

 /*Here is the style which does not apply when i deploy my app*/

    .Humburger {
        display: flex;
        justify-content: center;
        align-items: center;
        flex-flow: column;
        width: 35px;
        height: 100%;
        margin-left: 10px;
    }

/*==========================================================*/

.Humburger > span {
    display: inline-block;
    height: 5px;
    width: 100%;
    border-radius: 5px;
    background-color: #fff;
    margin-top: 3px;
    cursor: pointer;
}

.Humburger > span:first-child {
    margin: 0;
}

在ReactJs方面,我试图通过执行以下JS代码从我的api获取流:

[HttpGet("{clientid}/download/{filename}")]
public async Task<HttpResponseMessage> DownloadFileAsync([FromRoute] int clientid, [FromRoute] string filename)

问题是我收到如下所示的json响应,而不是二进制数据。

await fetch(`someservice/${clientid}/download/${fileName}`, { responseType: "arraybuffer" })
 .then(function (res) {
     var response = res;
     return response.body;
 })
.then(function (blob) {
    // Create an object URL for the blob object
    const url = URL.createObjectURL(blob);

    console.log(url);

    // Create a new anchor element
    const a = document.createElement('a');

    a.href = url;
    a.download = fileName || 'download';
    a.click();
})

更新1:

我已经更改了如下所示的提取方法,现在仅接收部分数据:

{
   "version":{
      "major":1,
      "minor":1,
      "build":-1,
      "revision":-1,
      "majorRevision":-1,
      "minorRevision":-1
   },
   "content":{
      "headers":[
         {
            "Key":"Content-Type",
            "Value":[
               "application/octet-stream"
            ]
         },
         {
            "Key":"Content-Length",
            "Value":[
               "119503316"
            ]
         }
      ]
   },
   "statusCode":200,
   "reasonPhrase":"OK",
   "headers":[
​
   ],
   "trailingHeaders":[
​
   ],
   "requestMessage":null,
   "isSuccessStatusCode":true
}

Results

更新2:

使用arrayBuffer后仍然有相同的部分数据接收事件

 await fetch(`someservice/${clientid}/download/${fileName}`)
             .then(function (res) {
                 var response = res;
                 return response.body;
             })
            .then(function (body) {
                    var reader = body.getReader()
                    var result;
                    var charsReceived = 0;

                    reader.read().then(function process({ done, value }) {

                        if (done) {
                            console.log("Stream complete");
                            return;
                        }

                        // value for fetch streams is a Uint8Array
                        const chunk = value;
                        charsReceived += value.length;
                        console.log(charsReceived);
                        result += chunk;

                        // Read some more, and call this function again
                        return reader.read().then(process);
                    });

                return result;
            })
            .then(function (blob) {
                // Create an object URL for the blob object
                const url = URL.createObjectURL(blob);

                console.log(url);

                // Create a new anchor element
                const a = document.createElement('a');

                a.href = url;
                a.download = fileName || 'download';
                a.click();
        })

1 个答案:

答案 0 :(得分:0)

我遇到了两个问题,并且已经修复了如下所示的javascript:

    await fetch(`lynxdumper/${clientid}/download/${fileName}`, { responseType: "blob" })
        .then((response) => {
            return response.blob();
         })
        .then(function (file) {
            console.log(file);
            let blob = new Blob([file], { type: 'dmp' });

            console.log(blob);
            // Create an object URL for the blob object
            const url = URL.createObjectURL(blob);

            console.log(url);

            // Create a new anchor element
            const a = document.createElement('a');

            a.href = url;
            a.download = fileName || 'download';
            a.click();
    })

而且我从以下位置更改了api端:

 Task<HttpResponseMessage> to Task<ActionResult<byte[]>> 

我的方法的完整代码如下:

    [HttpGet("{clientid}/download/{filename}")]
    public async Task<IActionResult> DownloadDumpFileAsync([FromRoute] int clientid, [FromRoute] string filename)
    {
        var client = clientRepository.GetClientById(clientid);

        var channel = GrpcChannel.ForAddress(client.BaseUrl.AbsoluteUri, new GrpcChannelOptions
        {
            HttpClient = CreateHttpClient(),
            MaxReceiveMessageSize = 1024 * 1024 * 1024,
            MaxSendMessageSize = 1024 * 1024 * 1024
        });

        var serviceclient = new DumperService.DumperServiceClient(channel);

        var replay = await serviceclient.DownloadAsync(new DowloadRequest { Filename = filename });
        var bytes = replay.Chunk.ToByteArray();

        return Ok(new MemoryStream(bytes));
    }