Как я могу получить содержимое Dynami c из файла .txt для отображения на нескольких страницах html, когда они загружаются динамически - PullRequest
1 голос
/ 14 июля 2020

У меня есть текстовый файл: 'm_data.txt' на сервере, который содержит 77 (например). Общее количество обновляется страницей pu sh. php, которая записывает в файл .txt.

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <meta name="generator" content="BBEdit 13.1" />
</head>
<body>




<form action="" method="get">

  <label for="number">RunningTotal:</label><br>
  <input type="text" id="number" name="number" value="0"><br>
  <input type="submit" id="submit" value="Submit">
  <!-- <input type="button" id="submit" value="Submit" onclick="sendform();"/> -->
  
</form>


<?php if (isset($_GET["number"])) { ?>


<p> Picked Up <?php echo $_GET["number"]; ?>.</p>

<?php
$myfile = fopen("m_data.txt", "w") or die("Unable to open file!");
$txt = $_GET['number']; 
fwrite($myfile, $txt);
fclose($myfile);
?>

<?php } ?>


</body>





</html>

Я хочу постоянно отображать эту сумму в пределах 2 страниц box1. html и box2. html

<!DOCTYPE html>
<html>
<head>
    <title>Box 1</title>

    <script type="text/javascript" src="autoM_Update.js"></script>
    
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

<style>
div.relative {
  position: relative;
  width: 900px;
  height: 250px;
  border: 1px solid black;
  background-color: white;
  text-align: center;
  font-size: 42px;
  line-height: 250px;
  margin: auto;
}
</style>

</head>
<body>

<div id="liveDataM" class="relative" class="anim" class="my_textBold">?</div>
</div>

</body>
</html>
<!DOCTYPE html>
<html>
<head>
    <title>Box 2</title>

    <script type="text/javascript" src="autoM_Update.js"></script>
    
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>

<style>
div.relative2 {
  position: relative;
  width: 900px;
  height: 175px;
  border: 1px solid black;
  background-color: white;
  text-align: center;
  font-size: 42px;
  line-height: 175px;
  margin: auto;
}

</style>

</head>
<body>

<div id="liveDataM" class="relative2" class="anim" class="my_textBold">?</div>
</div>

</body>
</html>

, если в текстовом файле изменяется общая сумма, она должна обновляться мгновенно на страницах на экране, без необходимости нажимать кнопку обновления страницы sh. Это выполняется с помощью файла autoM_Update. js, который также находится на сервере.

window.addEventListener('load', function()
{
    var xhr = null;

    getXmlHttpRequestObject = function()
    {
        if(!xhr)
        {               
            // Create a new XMLHttpRequest object 
            xhr = new XMLHttpRequest();
        }
        return xhr;
    };

    updateLiveData = function()
    {
        var now = new Date();
        // Date string is appended as a query with live data 
        // for not to use the cached version 
        var url = 'm_data.txt?' + now.getTime();
        xhr = getXmlHttpRequestObject();
        xhr.onreadystatechange = evenHandler;
        // asynchronous requests
        xhr.open("GET", url, true);
        // Send the request over the network
        xhr.send(null);
    };

    updateLiveData();

    function evenHandler()
    {
        // Check response is ready or not
        if(xhr.readyState == 4 && xhr.status == 200)
        {
            dataDiv = document.getElementById('liveDataM');
            // Set current data text
            dataDiv.innerHTML = xhr.responseText;
            // Update the live data every 1 sec
            setTimeout(updateLiveData(), 1000);
        }
    }
});

Это отлично работает, когда страницы box1 и box2 отображаются сами по себе. Кнопка refre sh не требуется быть нажатым. Каждый раз, когда я редактирую страницу pu sh. php, номер обновляется автоматически.

Но проблема в том, что я хочу, чтобы 2 страницы box1 и box2 отображались только при загрузке внутри append2. html .

<!DOCTYPE html>
<html>
<head>
    <title>Append2</title>

    <script type="text/javascript" src="autoM_Update.js"></script>
    

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>

<style>



body { 

}

table, th {
  table-layout: absolute;
  background-color: #FFFFFF;
  text-align: center;
  width: 900px;
  height: 40px;
  border: 1px solid black;
}

.div1 {
  margin:0 auto;
  text-align: center;
  line-height: 40px;
  height: 40px;
  width: 900px;
  border: 1px solid black;
  background-color: white;
}

div.relative {
  position: relative;
  width: 900px;
  height: 250px;
  text-align: center;
  line-height: 250px;
  margin: auto;
}

div.relative2 {
  position: relative;
  width: 900px;
  height: 175px;
  text-align: center;
  line-height: 175px;
  margin: auto;
}

</style>



</head>
<body>


<div ><button class="button1" onclick="getContent1();">Load Box1</button></div>
<br>
<div ><button class="button1" onclick="getContent2();">Load Box2</button></div>


<br>
<br>
<br>

<div class="div1" align="center">This is Today's Date</div>
<div class="relative" id="content1"></div>
<div class="relative2" id="content2"></div>
<br>
<br>
<br>

</body>

<script>


function getContent1() {
    $('#content1').load("box1.html");
}

function getContent2() {
    $('#content2').load("box2.html");
}


</script>

</html>

Когда ящики загружаются динамически, номер больше не отображается или обновляется. И даже простое нажатие кнопки refre sh для отображения числа не является для меня решением. Мне нужно, чтобы номер обновлялся автоматически при изменении файла .txt. Как я могу заставить изменения файла .txt распространяться вниз по цепочке на box1 и box2, если он загружен в файл append2. html. Мы будем очень признательны за любую помощь, понимание и примеры кода, которые вы можете мне дать.

Также используется getXmlHttpRequestObject в файле. js. Chrome выдает сообщение о том, что ... Синхронный XMLHttpRequest в основном потоке устарел из-за его пагубного воздействия на работу конечного пользователя. Каковы альтернативные решения этой проблемы, если это может не сработать в будущем. спасибо Марк.

1 Ответ

2 голосов
/ 14 июля 2020

Вместо бесконечного опроса с использованием XMLHttpRequest - где каждая из включаемых страниц предназначена для запуска запросов каждую секунду для получения одних и тех же данных, одна альтернатива, которую вы могли бы sh рассмотреть, - это использовать EventSource соединение в сочетании с postMessage

В приведенном выше коде вы надеетесь включить две страницы box в родительскую страницу (append2.html), но это будет недействительно как страница HTML может иметь только один раздел HTML, HEAD и BODY, поэтому включение целых веб-страниц внутри элементов DIV - это не способ продолжить - вместо этого очевидным выбором было бы использовать элементы iframe, которые загружают другие страницы. В демонстрации ниже эти окна iframe статически загружают страницы box1, box2, но вы можете загружать их динамически.

Для mimi c вашей настройки задействовано 5 страниц: -

sse.php ~ the file that reads the textfile every N seconds and sends data back
push.php ~ form that allows user to update text file with new number
append2.html ~ two statically declared iframes, content populated using `postMessage`
box1.html, box2.html ~ identical pages that `listen` for messages from append2.html

sse. php

<?php
    set_time_limit( 0 );
    ini_set('auto_detect_line_endings', 1);
    ini_set('max_execution_time', '0');
    ob_end_clean();
    

    $sleep=1;                   # send data every $sleep seconds
    $evt='txtupdate';           # Event name used in Javascript
    $file='m_data.txt';         # read this file for updated number
    
    #utility method to send formatted data
    function sse( $evtname='iss', $data=null, $retry=1000 ){
        if( !is_null( $data ) ){
            echo "event:".$evtname."\r\n";
            echo "retry:".$retry."\r\n";
            echo "data:" . json_encode( $data, JSON_FORCE_OBJECT );
            echo "\r\n\r\n";
        }
    }
    # headers... consider modifying `Allow-Origin` to increase security
    header('Content-Type: text/event-stream');
    header('Cache-Control: no-cache');
    header('Access-Control-Allow-Origin: *' );
    
    #infinite loop - read file and send data payload
    while( true ){
        if( connection_status() != CONNECTION_NORMAL or connection_aborted() ) break;
        
        $payload=[
            'count' =>  intval( file_get_contents( $file ) )
        ];
        call_user_func( 'sse', $evt, $payload );
        
        /* -- Send output -- */
        if( @ob_get_level() > 0 ) for( $i=0; $i < @ob_get_level(); $i++ ) @ob_flush();
        @flush();
        
        sleep( $sleep );
        $payload = null;
    }
    
    if( @ob_get_level() > 0 ) {
        for( $i=0; $i < @ob_get_level(); $i++ ) @ob_flush();
        @ob_end_clean();
    }
?>

pu sh. php

<?php
    $file='m_data.txt';         # read & update this file ( same as referenced in SSE )
    $autoupdate=true;           # does the user need to manually update the number in the form?
    $int=file_exists( $file ) ? intval( file_get_contents( $file ) ) : 0;
    
    if( $_SERVER['REQUEST_METHOD']=='POST' && isset( $_POST['action'] ) ){
        ob_clean();
        $json=[];
        
        if( $_POST['action'] == 'update-file' ){
            $number=intval( $_POST['number'] );
            if( $autoupdate ) $number++;
            
            file_put_contents( $file, $number );
            $json=json_encode( array( 'number'=>$number ) );
        }
        exit( $json );
    }
?>
<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>push</title>
        <script>
            /*
                send ajax request to server, update source textfile
                and return the new count. Use the callback to update
                the displayed number.
            */
            document.addEventListener('DOMContentLoaded',(e)=>{
                let form=document.forms.push;
                let bttn=form.querySelector('[type="button"]');
                
                bttn.addEventListener('click',()=>{
                    
                    let fd=new FormData( form );
                        fd.append('action','update-file');
                        
                    fetch( location.href, { method:'post',body:fd } )
                        .then( r=>{ return r.json() })
                        .then( json=>{
                            form.number.value=json.number;
                        })                  
                });
            })
        </script>
    </head>
    <body>
        <form name='push'>
            <label>Number: <input type='number' name='number' value='<?=$int;?>' /></label>
            <?php
                if( $autoupdate ){
                    echo "
                    <p>You do NOT need to manually update this number - simply click the button to increment the counter by 1</p>";
                }
            ?>
            <input type='button' value='Update' />
        </form>
    </body>
</html>

append2. html

<!DOCTYPE html>
<html lang='en'>
    <head>
        <meta charset='utf-8' />
        <title>Display</title>
        <style>
            iframe{
                width:30%;
                margin:1rem;
                border:5px dashed rgba(100,100,100,0.25);
                border-radius:1rem;
                background:whitesmoke;
                padding:0;
            }
        </style>
        <script>
            let evtsource = new EventSource( 'sse.php', { withCredentials: false } );
                evtsource.addEventListener( 'txtupdate', function(e){
                    if( !e.origin == window.location.origin ) return false;
                    let json=JSON.parse( e.data );
                    
                    let b1=document.getElementById('b1').contentWindow;
                    let b2=document.getElementById('b2').contentWindow;
                    
                        b1.postMessage( json.count );
                        b2.postMessage( json.count );
                });
        </script>
    </head>
    <body>
        <!-- box 1 -->
        <iframe id='b1' src='box1.html'></iframe>
        
        <!-- box 2 -->
        <iframe id='b2' src='box2.html'></iframe>
    </body>
</html>

box1 & box2

<!DOCTYPE html>
<html lang='en'>
    <head>
        <title>Box 1||Box 2</title>
        <script>
            window.addEventListener( 'message', (e)=>{
                if( e.origin == window.location.origin ){
                    document.getElementById('liveDataM').textContent=e.data;
                }
            });
        </script>
    </head>
    <body>
        <div id='liveDataM' class='relative anim my_textBold'></div>
    </body>
</html>

Откройте две вкладки браузера - загрузите push.php в одну и append2.html в другую и обновите текстовый файл, чтобы увидеть значение, отображаемое одновременно в обоих фреймах. Надеюсь, это поможет /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...