Я прочитал много подобных вопросов об отмене запроса POST с помощью jQuery, но ни один из них не кажется близким к моему.
У меня есть ваша повседневная форма с PHP-страницей в качестве действия:
<form action="results.php">
<input name="my-input" type="text">
<input type="submit" value="submit">
</form>
Обработка results.php
на стороне сервера на основе информации о сообщении, указанной в форме, занимает много времени (30 секунд или даже больше, и мы ожидаем увеличения, потому что наше пространство для поиска также увеличится в ближайшие недели). Мы обращаемся к серверу Basex (версия 7.9, без возможности обновления), который содержит все данные. Сгенерированный пользователем код XPath отправляется в форму, а затем URL-адрес действия отправляет код XPath на сервер Basex, который возвращает результаты. С точки зрения удобства использования я уже показываю экран загрузки, чтобы пользователи, по крайней мере, знали, что результаты генерируются:
$("form").submit(function() {
$("#overlay").show();
});
<div id="overlay"><p>Results are being generated</p></div>
Однако я также хотел бы предоставить пользователям возможность нажать кнопку для отмены запроса и отменить запрос, когда пользователь закрывает страницу. Обратите внимание, что в первом случае (при нажатии кнопки) это также означает, что пользователь должен оставаться на той же странице, может редактировать свой ввод и немедленно повторно отправлять свой запрос. Крайне важно, чтобы при отмене запроса они также могли немедленно отправить его повторно: сервер должен на самом деле прервать и не завершить запрос, прежде чем он сможет обработать новый запрос.
Я придумал что-то вроде этого:
$("form").submit(function() {
$("#overlay").show();
});
$("#overlay button").click(abortRequest);
$(window).unload(abortRequest);
function abortRequest() {
// abort correct request
}
<div id="overlay">
<p>Results are being generated</p>
<button>Cancel</button>
</div>
Но, как видите, я не совсем уверен, как заполнить abortRequest
, чтобы убедиться, что запрос на публикацию прерван, и завершен, чтобы можно было отправить новый запрос. Пожалуйста, заполните пропуски! Или мне нужно .preventDefault()
отправить форму и вместо этого сделать вызов ajax() из jQuery?
Как я уже сказал, я также хочу остановить процесс на стороне сервера, и из того, что я прочитал, мне нужно exit()
для этого. Но как я могу exit
использовать другую функцию PHP? Например, предположим, что в results.php
у меня есть сценарий обработки, и мне нужно выйти из этого сценария, должен ли я сделать что-то подобное?
<?php
if (isset($_POST['my-input'])) {
$input = $_POST['my-input'];
function processData() {
// A lot of processing
}
processData()
}
if (isset($_POST['terminate'])) {
function terminateProcess() {
// exit processData()
}
}
а затем сделать новый запрос ajax, когда мне нужно завершить процесс?
$("#overlay button").click(abortRequest);
$(window).unload(abortRequest);
function abortRequest() {
$.ajax({
url: 'results.php',
data: {terminate: true},
type: 'post',
success: function() {alert("terminated");});
});
}
Я провел еще несколько исследований и нашел этот ответ. В нем упоминается connection_aborted(), а также session_write_close(), и я не совсем уверен, что мне полезно. Я использую переменные SESSION, но мне не нужно записывать значения при отмене процесса (хотя я хотел бы, чтобы переменные SESSION оставались активными).
Будет ли это путь? И если да, то как заставить одну функцию PHP завершить другую?
Я также читал о веб-сокетах, и мне кажется, что это может работать, но мне не нравятся проблемы с настройкой сервера веб-сокетов, поскольку для этого мне потребуется связаться с нашим ИТ-специалистом, которому требуется тщательное тестирование новых пакетов. Я бы предпочел использовать PHP и JS без сторонних библиотек, кроме jQuery.
Учитывая, что большинство комментариев и ответов предполагают, что то, что я хочу, невозможно, мне также интересно услышать альтернативы. Первое, что приходит на ум, это постраничные вызовы Ajax (аналогично многим веб-страницам, которые предоставляют результаты поиска, изображения и все, что у вас есть, в бесконечной прокрутке). Пользователю предоставляется страница с первыми результатами X (например, 20), и когда они нажимают кнопку «показать следующие 20 результатов», они добавляются. Этот процесс может продолжаться до тех пор, пока не будут показаны все результаты. Поскольку пользователям полезно получать все результаты, я также предоставлю опцию «загрузить все результаты». Это также займет очень много времени, но, по крайней мере, пользователи должны иметь возможность просмотреть первые результаты на самой странице. (Таким образом, кнопка загрузки не должна прерывать постраничную загрузку Ajax.) Это всего лишь идея, но я надеюсь, что она вдохновит некоторых из вас.