skip to Main Content

I need to make a call to a file named chiamata_preventivo.php, which takes about 10 minutes to respond. While this page is being processed, I would like to open a new tab to dashboard.php to allow the user to navigate while the request is being processed. The issue is that the call is blocking, and I’m unable to make it work with fetch() or an AJAX call.

Main file (this script is in the HTML head):

<script>
        document.addEventListener("DOMContentLoaded", async function() {
            try {
                const response = await fetch('chiamata_preventivo.php', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({ datiJson: <?php echo $json; ?> })
                });
                const data = await response.json();
                console.log(data);

                // Open the dashboard in a new tab
                window.open("../../common_page/dashboard.php", "_blank");
            } catch (error) {
                alert('Error in request: ' + error);
            }
        });
    </script>

chiamata_preventivo.php

<?php
$_pageProfile = "*";
$nome_pagina = "chiamata_preventivo.php";

require_once $_SERVER['DOCUMENT_ROOT'] . '/common/database_connect.php';
require_once $_SERVER['DOCUMENT_ROOT'] . '/interfacce/bartolini/richiesta_bartolini.php';

header('Content-Type: application/json');

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    $input = file_get_contents('php://input');
    $dati = json_decode($input, true);
    $json = $dati["datiJson"];

    $response = dispatchRequestRCA(json_encode($json));
    echo json_encode($response);
    die();
}
?>

Any solutions?

2

Answers


  1. The await will pause the execution:

    await is usually used to unwrap promises by passing a Promise as the expression. Using await pauses the execution of its surrounding async function until the promise is settled (that is, fulfilled or rejected). When execution resumes, the value of the await expression becomes that of the fulfilled promise. (await | MDN)

    Therefor the code after your fetch request only run after the fetch request promise has returned.

    You can call the fetch function without the await and then use Promise.prototype.then() to do stuff when the promise of the request is returned.

    document.addEventListener("DOMContentLoaded", function() {
      fetch('data:application/json,{"status":"OK"}', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          datiJson: 'test'
        })
      }).then(res => res.json()).then(data => {
        console.log(data);
      });
      // Open the dashboard in a new tab
      // but not functional on stackoverflow
      //window.open("../../common_page/dashboard.php", "_blank");
      console.log('call the window.open function');
    });
    Login or Signup to reply.
  2. Okay so there is a way to resolve this but its a bad idea.

    Let me start with how to fix it… Then Ill explain why the "fix" is a bad idea.

    in your chiamata_preventivo.php file you will need to add at the top of the file.

    ini_set('memory_limit', '-1');
    ini_set('max_execution_time', '0');
    ini_set('max_input_time', '-1');
    

    This basically lets php run as long as needed and allows it to take up as much memory as needed. There are times when browsers need to run a process longer than the standard timeout (usually 30 seconds).

    Now heres why this is a BAD idea:

    Not only is it bad UX to make a user watch a spinner for 10 minutes, there are security risks to leaving a connection open that long.

    If you have to change the memory limit, that means you have a memory leak, and/or you’re trying to execute something in the browser that should be done via exec or shell_exec

    That being said, controlling the memory limit and execution time from your php controller should allow the ajax request to not get "blocked" (the real term is "timeout")

    Please do not use my solution. But if you do, it will "fix" your issue.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search