这个问题还没有完全回答,欢迎投稿!
我正在尝试显示一个简单的 progress bar
提交大表单时。
该表单包含十几个字段,以及一些文件上传字段,用户可以在其中选择图片。然后,当他点击 Create
按钮,提交带有数据和图片的表单,并在数据库中创建实体。 (只需单击一下即可提交表格和图片)。
一切正常,但我想在提交过程中显示一个进度条。
我找到了很多教程来解释如何显示进度条,但我找不到任何人解释如何显示进度条以指示方法完成的工作百分比,即,我希望在提交过程中看到 10%、25% 等...。
所以,基本上,这就是我所做的:(这是一个 ASP.NET MVC3 项目)
@model MyModel
@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "target-form", enctype = "multipart/form-data" }))
{
//some Html.TextBoxFor() and other @Html.DropDownListFor
@Html.TextBoxFor(m => m.File, new { type = "file"})
<input type="submit" value="Create" class="submitButton" />
<div id="progressBar"></div>
}
还有一个基本的 Controller
[HttpPost]
public ActionResult Create(MyModel model)
{
if (ModelState.IsValid)
{
DALLayer dal = new DALLayer()
dal.AddEntity(model);
return RedirectToAction("Index", "Home");
}
return null;
}
有没有可能改造我最后一个<div>
在progressBar
显示上传进度状态?
这是我的要求:
- 没有插件(这是一个个人项目,我想自己了解如何做)。
- 交叉兼容,IE8+(如果可能)
- jQuery 可以,但没有 Flash。
非常感谢你 !
更新 1
这是一个JSFIDDLE ,我正在努力适应 this link但没有成功......如果你认为你可以提供帮助,不客气!
更新 2
好的,我用了acarlon's answer用 XMLHttpRequest
提交我的表格并且数据已正确发布到 Controller 。但是,ProgressBar 仍然没有出现!
我只是将传递给 Controller 的数据替换为:
formData = new FormData(document.getElementById("target-form") );
xhr.open("POST", "@Url.Action("MyMethod", "MyController")", true );
并尝试一些不同的 header ,例如:
xhr.setRequestHeader("X-File-Name", $('#Files_0__File')[0].files[0].name);
xhr.setRequestHeader("X-File-Size", $('#Files_0__File')[0].files[0].size);
xhr.setRequestHeader("X-File-Type", $('#Files_0__File')[0].files[0].type);
//Also tried with "Content-Length" but it doesn't care about it.
(它在这里被硬编码以确保它具有良好的值(value)。当我对它更放心时,我会在一个循环中完成它。)
当我提交表单时,XMLHttpRequest
send 有这些字段:
readyState: 4
status: 0 <= should be 200, right ?
并且在 error handler
,我有这些值(value)观:
loaded: 0
total: 883526
type: "error"
所以数据已提交到我的 Controller ,但我无法显示这个该死的进度条...
最佳答案
您可以使用 XMLHttpRequest
在上传文件时接收更新。还有各种 jquery 类型的包装器可以实现相同的目的。我将描述使用 XMLHttpRequest
的解决方案。
首先拦截表单提交。
$("#target-form").submit(function () {
然后创建XHR请求:
xhr = new XMLHttpRequest();
然后注册以获取有关进度事件的通知:
xhr.upload.addEventListener( "progress", function ( evt )
{
if( evt.lengthComputable )
{
var progressPercent = ( evt.loaded / evt.total ) * 100;
showProgress( value );//your function.
}
}, false );
//Some other events you will probably want to subscribe to
xhr.addEventListener( "load", function ()
{
fileUploadComplete( this.responseText );
}, false );
xhr.addEventListener( "error", function ( first, second, third )
{
fileUploadComplete( "Error: Image format not supported." );
}, false );
xhr.addEventListener( "abort", function ()
{
fileUploadComplete( "Error: Upload was cancelled. Please try again." );
}, false );
打开 XHR 传入任何参数(id
显示为示例)
xhr.open( "post", '@Html.Raw( @Url.Action( "UploadImage", new { someId = id } ) )', true );
// Set appropriate headers
xhr.setRequestHeader( "Content-Type", "multipart/form-data" );
xhr.setRequestHeader( "X-File-Name", name );
// Send the file
xhr.send( file );
然后在 Controller 中:
public ActionResult UploadImage( int someId, HttpPostedFileBase userFile )
{
...
}
您将在更新处理程序中收到更新。
长时间运行的服务器任务的扩展
如果服务器上有一些长时间运行的任务(例如将数据写入数据库),那么您需要在服务器上对操作进行分块(以便您可以在每个分块完成时提供更新)并实现代码处理可以从 javascript 查询的长时间运行的服务。参见 here .基本思想是在服务器端启动任务并定期从 Javascript 检查进度。您可能希望有两个单独的进度条,一个用于上传,一个用于服务器端操作。这为用户提供了更多信息——他们将知道文件上传已完成,现在一些服务器端操作正在发生。
关于javascript - 显示一个进度条,显示表单提交的进度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21902385/