Чтобы избежать ошибки "бесконечная загрузка страницы" при отправке POST-запроса, вы должны убедиться, что серверный код Go обрабатывает запрос в фоновом режиме не блокируя основной поток. В предоставленном вами примере уже используется горутина для отправки сообщений в асинхронном режиме. Однако, чтобы это работало корректно, вам нужно также отправлять ответ обратно клиенту (например, статус операции), чтобы браузер знал, что запрос был обработан.
Чтобы обновлять счетчик отправленных сообщений без ожидания окончания цикла, вы можете использовать веб-сокеты или долгие опросы (long polling), чтобы поддерживать открытое соединение между сервером и клиентом. Тем не менее, более простой способ решения является использование AJAX для асинхронного обновления интерфейса.
Вот как это может быть реализовано:
1. Измените серверный код, чтобы он возвращал JSON-ответ вместо запуска бесконечной загрузки страницы. Это можно сделать, добавив endpoint, который будет выдавать текущий статус отправленных сообщений.
2. Используйте AJAX для отправки данных формы и обновления счетчика отправленных сообщений на странице не блокируя интерфейс пользователя.
3. С помощью JavaScript на стороне клиента регулярно опрашивайте сервер о статусе отправленных сообщений и обновляйте интерфейс, получив новые данные.
Вот как это может быть организовано в коде:
### Изменения в Go файле:
```go
// Функция для отслеживания счетчика
var messageCounter int64
func sendMessageHandler(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
go func() {
for i, number := range numbers[:messageCount] {
err := utils.SendMessage(session, number, message)
if err != nil {
log.Printf("Error while sending message: %s\n", err)
} else {
atomic.AddInt64(&messageCounter, 1) // Увеличиваем счетчик атомарно
log.Printf("%d. Отправлено сообщение: [%s - %s]", i, number, sessionName)
sleepTime := time.Duration(delay) * time.Second
time.Sleep(sleepTime)
}
}
}()
w.WriteHeader(http.StatusAccepted) // Отправляем ответ об успешном начале отправки сообщений
return
}
}
func getMessageCounterHandler(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
count := atomic.LoadInt64(&messageCounter) // Получаем значение счетчика атомарно
json.NewEncoder(w).Encode(map[string]int64{"count": count})
}
```
### Изменения в HTML и JavaScript:
```html
<form id="sendMessageForm" action="/send_messages" method="post">
...
<button type="submit" id="sendMessageBtn" class="btn btn-primary">Запустить</button>
</form>
<p>Отправлено сообщений: <span id="messageCount">0</span></p>
<script>
$('#sendMessageForm').submit(function(e) {
e.preventDefault();
$.ajax({
type: 'POST',
url: $(this).attr('action'),
data: $(this).serialize(),
success: function(data) {
// При успехе начинаем опрос сервера на предмет обновлений счетчика
updateMessageCount();
}
});
});
// Функция для опроса счетчика
function updateMessageCount() {
setInterval(function() {
$.getJSON('/get_message_counter', function(data) {
$('#messageCount').text(data.count);
});
}, 1000);