[英]How can I get dynamic content from a .txt file to display in multiple html pages when they are loaded dynamically
我在服務器上有一個文本文件:'m_data.txt',其中運行總數為 77(例如)。 總數由寫入 .txt 文件的 push.php 頁面更新。
<!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>
如果在 txt 文件中更改了總數,它應該立即在屏幕上的頁面中更新,而無需點擊頁面刷新按鈕。 這也是通過服務器上的“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 自己顯示時,這可以正常工作。不需要按下刷新按鈕。 每當我編輯 push.php 頁面時,數字都會自動更新。
但問題是,我希望只有在 append2.html 中加載時才會出現 2 頁 box1 和 box2。
<!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>
動態加載框時,數字不再出現或更新。 即使只是單擊刷新按鈕來獲取要顯示的數字對我來說也不是解決方案。 每當更改 .txt 文件時,我都需要自動更新號碼。 如果將 .txt 文件更改加載到 append2.html 文件中,如何獲取該文件更改以沿鏈傳播到 box1 和 box2。 您可以給我的任何幫助、見解和代碼提供的示例將不勝感激。
這也是在 .js 文件中使用 getXmlHttpRequestObject 。 Chrome 正在發出一條消息……主線程上的同步 XMLHttpRequest 已被棄用,因為它對最終用戶的體驗產生不利影響。 如果這可能無法解決,有什么替代解決方案可以解決這個問題。 謝謝馬克。
而不是使用XMLHttpRequest
無休止地輪詢 - 其中要包含的每個頁面都旨在每秒觸發請求以檢索相同的數據,您可能希望考慮的一種替代方法是將EventSource
連接與postMessage
結合使用
在上面的代碼中,您希望在父頁面( append2.html
)中包含兩個box
頁面 - 但這樣做是無效的,因為BODY
頁面只能有一個HTML
頁面,因此在HEAD
和內部包含整個網頁部分DIV 元素不是繼續的方式 - 相反,顯而易見的選擇是使用加載其他頁面的iframe
元素。 在下面的演示中,這些 iframe 靜態加載 box1、box2 頁面,但您可以動態加載這些頁面。
為了模仿您的設置,涉及 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();
}
?>
push.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>
盒子 1 和盒子 2
<!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
並更新文本文件以同時查看兩個 iframe 中反映的值。 希望能幫助到你/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.