Мне недавно пришлось самостоятельно реализовывать этот тип функций, и этот вопрос и ссылка на блог Джесси Табера оказались очень полезными, поэтому я решил поделиться своей реализацией с использованием ASP.NET MVC.
Основная теория заключается в том, что вы передаете токен контроллеру при отправке формы, и контроллер устанавливает cookie с этим значением в ответе, когда происходит загрузка.
(извинения за VB.NET)
Добавьте свойство к вашей модели для хранения токена:
Public Property DownloadToken As String
Затем установите cookie в ответ, прежде чем возвращать результат:
If Response.Cookies("MyFileDownloadToken") Is Nothing Then
Dim cookie As New HttpCookie("MyFileDownloadToken", ParameterModel.DownloadToken)
Response.Cookies.Add(cookie)
Else
Response.Cookies("MyFileDownloadToken").Value = ParameterModel.DownloadToken
End If
Добавьте свойство токена как скрытое поле в вашей форме:
@Html.HiddenFor(Function(m) m.DownloadToken)
Затем мы можем использовать JavaScript для управления кнопкой sumbit и плагином jQuery Cookie для получения и установки значения файлов cookie.
var fileDownloadChecker;
$(function ()
{
$("#MyForm").submit(function ()
{
$(".validation-summary-errors").empty(); //Clear any validation errors from a previous failed form submission
PreventResubmission();
});
$("#submitButton").prop("disabled", false);
}
function PreventResubmission()
{
//Use the current time as a unique token that we can check for in the response
var token = new Date().getTime();
//Set the token so that it is passed through to the controller
$("#DownloadToken").val(token);
//Prevent the user from resubmitting the form
$("#submitButton").prop("disabled", true);
$("#submitButton").val("Running...");
//Check once a second for the token in the response
fileDownloadChecker = window.setInterval(function ()
{
var cookieValue = $.cookie("MyFileDownloadToken");
if (cookieValue == token)
{
EnableFormSubmission();
}
}, 1000);
}
function EnableFormSubmission()
{
//Stop checking for the token
window.clearInterval(fileDownloadChecker);
fileDownloadChecker = 0;
//Clear the hidden field
$("#DownloadToken").val("");
//Clear the cookie that contains the token
$.cookie("MyFileDownloadToken", null, { path: "/" });
//Enable the form submit button
$("#submitButton").prop("disabled", false);
$("#submitButton").val("Run");
}
Что следует отметить:
1) Параметры пути по умолчанию для класса HttpCookie и интерфейса Cookie jQuery отличаются. По умолчанию HttpCookie создается в корневом каталоге ('/'), тогда как плагин jQuery будет искать (и устанавливать) файлы cookie на основе текущего пути. Если вы читаете куки-файл, он затем откатится и будет искать другие пути. Поэтому мы указываем путь по крайней мере при очистке куки. (Попал в ситуацию, когда код работал бы один раз, но впоследствии не работал, потому что он находил бы cookie в текущем пути и всегда возвращал это значение)
2) Я добавил строку для включения кнопки отправки при загрузке страницы, потому что, если страница обновилась по какой-либо причине во время рабочей фазы, она сохранит состояние «отключено» кнопки.
3) Если ваша страница похожа на мою, на ней отображаются ошибки проверки модели, НО страница никогда не обновляется при успешной отправке, поэтому все предыдущие ошибки проверки будут по-прежнему отображаться в форме. Я добавил строку в обработчик события submit формы, чтобы очистить любые дочерние элементы от любого элемента с классом ".validation-summary-errors".