jquery 通过Azure Blob存储上传时浏览器没有响应

ua4mk5z4  于 2023-10-17  发布在  jQuery
关注(0)|答案(1)|浏览(117)

我有一个项目,用户可以上传文件到云存储和上传大文件显然需要一些时间来做,我明白。但是,如果文件足够大,当上传到云的过程正在运行时,浏览器(在我的情况下是Chrome)将看到网页没有响应,并给予用户杀死页面或等待的选项。我现在的目标是做一些事情,不让浏览器给予用户杀死页面的选择,本质上是做一些事情,向客户端系统发送信号,并看到页面响应,但我正在努力找到一种方法。
我的第一个想法是添加某种进度条来跟踪上传进度,无论是通过gif,ui进度条,还是写入控制台,但所有这些都失败了。一旦上传进程开始,屏幕将冻结。您仍然可以在另一个选项卡中执行操作,但是处于上传进度中间的选项卡卡住了,浏览器会将此视为页面没有响应,因此会询问用户是否要杀死该页面。上传仍在进行中,在这个阶段,杀死页面将取消上传。
当我尝试添加加载GIF之类的东西时,它将在调用upload方法之前显示,但它不会显示。然而,只有在这个过程完成后,它才能看到一瞬间,因为页面被设置为在上传过程后重新加载。
当我尝试Console.WriteLine()方法时,在整个上传过程中,浏览器调试器的控制台上什么也没有显示。
我为它做的代码看起来像下面这样。

function CallUploadFile(fileData, successFunction, errorFunction) {
    $('#loading-gif').show()
    // Calling method where upload to Blob Storage is after showing loading gif
    $.ajax({
        url: '/File/UploadFile',
        type: 'post',
        data: data,
        async: true,
        success: function (fileData) { successFunction(fileData); },
        error: function (fileData) { errorFunction(fileData); },
        ...
    });
}

下面是我的mixadFile方法的样子:

public async Task<string> UploadFile() {
    BlobServiceClient service = new BlobServiceClient(connectionString);
    BlobContainerClient containter = blobServiceClient.GetBlobContainerClient(blobContainer);
    BlockBlobClient block = container.GetBlockBlobClient(fileName);

    using (Stream stream = inputStream) {
        byte[] buffer = new byte[1024 * 1024 * 50];
        int bytesRead;
        int blockNumber = 0;

        while ((bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length)) > 0) {
            using (MemoryStream chunkStream = new MemoryStream(buffer, 0, bytesRead))
            {
                string blockId = Convert.ToBase64String(BitConverter.GetBytes(blockNumber));
                await block.StageBlockAsync(blockId, chunkStream);
                blockNumber++;
            }
        }
        var blockList = Enumerable.Range(0, blockNumber)
            .Select(x => Convert.ToBase64String(BitConverter.GetBytes(x)))
            .ToList();
        await block.CommitBlockListAsync(blockList);
    }
    return "Success";
}

我不知道如何从这里开始,希望得到一些帮助。

-更多信息-

我上传文件的页面是一个 * 部分 * 视图,位于各种视图页面中,因此上传的文件可以分为相应的类别。此外,上传文件的按钮是一个保存按钮,它还可以同时删除文件和保存对页面的更改。这引入了复杂性,因为现在可以多次调用其他函数和动作方法,如DeleteFile()和DeletadFile()。

3lxsmp7m

3lxsmp7m1#

您在Chrome中遇到的“杀死页面”通知问题可能是因为浏览器认为页面在文件上传过程中没有响应。为了防止这种情况并提供更好的用户体验,我们可以在文件上传过程中实现进度条并改进反馈。
下面的代码跟踪进度条来跟踪上传进度。在显示“文件已上传”消息10秒后,进度条将重置为零,单击“选择文件”也将重置进度条为零。

@{
    ViewData["Title"] = "File Upload";
}

<h2>File Upload</h2>

<form asp-controller="FileUpload" asp-action="UploadFile" method="post" enctype="multipart/form-data">
    <div class="form-group">
        <label for="file">Select a File:</label>
        <input type="file" name="file" id="file" class="form-control-file">
    </div>

    <button type="submit" class="btn btn-primary">Upload</button>
</form>

<div id="loading" class="text-center" style="display: none;">
    <img src="/images/loading.gif" alt="Loading...">
</div>

<div id="progress-container" class="mt-4">
    <div class="progress">
        <div class="progress-bar" id="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
            0%
        </div>
    </div>
</div>

<div id="file-uploaded" class="alert alert-success mt-3" style="display: none;">
    File Uploaded!
</div>

<div id="error-message" class="alert alert-danger mt-3" style="display: none;">
    Error Uploading File. Please try again.
</div>

<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script type="text/javascript">
    $(document).ready(function () {
        $('form').submit(function () {
            var formData = new FormData($(this)[0]);

            $.ajax({
                url: '/FileUpload/UploadFile',
                type: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                xhr: function () {
                    var xhr = new window.XMLHttpRequest();
                    xhr.upload.addEventListener('progress', function (e) {
                        if (e.lengthComputable) {
                            var percent = (e.loaded / e.total) * 100;
                            $('#progress-bar').css('width', percent + '%').attr('aria-valuenow', percent);
                            $('#progress-bar').text(percent.toFixed(2) + '%');
                        }
                    });
                    return xhr;
                },
                beforeSend: function () {
                    $('#loading').show();
                    $('#progress-bar').css('width', '0%').text('0%');
                    $('#file-uploaded').hide();
                    $('#error-message').hide();
                },
                complete: function () {
                    $('#loading').hide();
                },
                success: function (data) {
                    // Handle success (e.g., display a success message)
                    $('#file-uploaded').show();
                    setTimeout(function () {
                        $('#progress-bar').css('width', '0%').text('0%');
                        $('#file-uploaded').hide();
                    }, 10000); // Reset after 10 seconds
                },
                error: function () {
                    // Handle error (e.g., display an error message)
                    $('#error-message').show();
                    $('#progress-bar').css('width', '0%').text('0%');
                    setTimeout(function () {
                        $('#error-message').hide();
                    }, 5000); // Hide error message after 5 seconds
                }
            });

            return false;
        });

        // Reset progress bar to zero when the "Choose File" button is clicked
        $('#file').click(function () {
            $('#progress-bar').css('width', '0%').text('0%');
        });
    });
</script>

控制器

public class FileUploadController : Controller
 {
     private const string AzureStorageConnectionString = "";
     private const string ContainerName = "";

     [HttpGet]
     public IActionResult Index()
     {
         return View();
     }

     [HttpPost]
     public async Task<IActionResult> UploadFile()
     {
         try
         {
             var file = Request.Form.Files[0];

             if (file == null || file.Length == 0)
             {
                 return RedirectToAction("Index");
             }

             // Create a BlobServiceClient using the connection string
             var blobServiceClient = new BlobServiceClient(AzureStorageConnectionString);

             // Get a container client
             var containerClient = blobServiceClient.GetBlobContainerClient(ContainerName);

             // Upload the file
             var blobClient = containerClient.GetBlobClient(file.FileName);
             using (var stream = file.OpenReadStream())
             {
                 await blobClient.UploadAsync(stream, true);
             }

             // Handle success and return a response
             return RedirectToAction("Index");
         }
         catch (Exception ex)
         {
             // Handle errors here
             return RedirectToAction(ex + "Index");
         }
     }
 }

上传开始前要显示的加载GIF行为:

<script type="text/javascript">
    $(document).ready(function () {
        $('#file').click(function () {
            $('#progress-bar').css('width', '0%').text('0%');
            $('#file-uploaded').hide();
            $('#error-message').hide();
        });

        $('form').submit(function () {
            var formData = new FormData($(this)[0]);

            $.ajax({
                url: '/FileUpload/UploadFile',
                type: 'POST',
                data: formData,
                processData: false,
                contentType: false,
                xhr: function () {
                    var xhr = new window.XMLHttpRequest();
                    xhr.upload.addEventListener('progress', function (e) {
                        if (e.lengthComputable) {
                            var percent = (e.loaded / e.total) * 100;
                            $('#progress-bar').css('width', percent + '%').attr('aria-valuenow', percent);
                            $('#progress-bar').text(percent.toFixed(2) + '%');
                        }
                    });
                    return xhr;
                },
                beforeSend: function () {
                    $('#loading img').show();
                    $('#progress-container').show();
                },
                complete: function () {
                    $('#loading img').hide();
                    $('#file-uploaded').show();

                    // Reset the progress bar and messages after 10 seconds
                    setTimeout(function () {
                        $('#progress-bar').css('width', '0%').text('0%');
                        $('#file-uploaded').hide();
                        $('#error-message').hide();
                    }, 10000);
                },
                success: function (data) {
                    // Handle success (e.g., display a success message)
                },
                error: function () {
                    $('#error-message').show();
                }
            });

            return false;
        });
    });
</script>

相关问题