Как можно избежать ошибки "бесконечная загрузка страницы" при отправке post запроса?

Как можно обновлять счетчик отправленных сообщений без ожидания окончания цикла при отправке POST-запроса в функцию? Как использовать Ajax для обновления счетчика отправленных сообщений без блокирования интерфейса? 

general.go
```go
if r.Method == http.MethodPost {
    go func() {
        for i, number := range numbers[:messageCount] {
            err := utils.SendMessage(session, number, message)
            if err != nil {
                log.Fatalf("Error while sending message: %s\n", err)
            } else {
                logMessage := fmt.Sprintf("%d. Отправлено сообщение: [%s - %s]", i, number, sessionName)
                fmt.Println(logMessage)
                sleepTime := time.Duration(delay) * time.Second
                time.Sleep(sleepTime)
            }
        }
    }()
}
```
index.html
```html
<form id="sendMessageForm" action="/send_messages" method="post">
    ...
    <button type="submit" id="sendMessageBtn" class="btn btn-primary">Запустить</button>
</form>
<script>
    $('#sendMessageForm').submit(function(e) {
        e.preventDefault();
        $.post($(this).attr('action'), $(this).serialize(), function(data) {
            // Обновить счетчик отправленных сообщений здесь
        });
    });
</script>
```
  • 22 января 2024 г. 10:19
Ответы на вопрос 2
Чтобы избежать ошибки "бесконечная загрузка страницы" при отправке 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);
Ну... Вот структура ajax скрипта для post запроса (Только вам нужно сначала ещё подключить jQuery, потому что ajax является частью библиотеки jQuery): 


Этот скрипт будет выполняться асинхронно и пользователю не придётся ждать его завершения, а когда запрос будет выполнен, вы сможете его обработать в блоках success и error
Похожие вопросы