Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 19.08.2022, 13:19
Аспирант
Отправить личное сообщение для Olga27 Посмотреть профиль Найти все сообщения от Olga27
 
Регистрация: 10.06.2021
Сообщений: 49

Код плохо запускается в режиме реального времени. Как исправить?
У меня есть json документ, в отдельном файле я его подгружаю с помощью ajax, потом вношу в него изменения и сохраняю повторно. Смысл работы скрипта заключается в следующем. Есть “посты” в них вложены картинки, у каждого поста существует статус который принимает три значение “ok”, “wait” и “current”. У картинок тоже есть эти статусы. В каждом посте может быть несколько картинок.

В итоге скрипт каждую секунду открывает ветку поста проходит по картинкам и всем присваивает статус ok, дальше когда все картинки у поста закончились и они получили свой статус ok, главному посту также присваивается status ok и так до конца json документа.
Вот пример на картинке, как это работает.
example1.jpg
Проблема заключается в следующем скрипт плохо работает в режиме реального времени. Т.е. при первом запуске ничего не происходит. Я достаточно долго пыталась разобраться в чем ошибка. Пока не связалась с json документом, указав в браузере прямой путь, и не обновила этот документ. Пример на картинки.
example2.jpg
После обновления в открытом окне скрипт сразу стал работать в реальном времени.

В чем здесь может быть проблема? Я забыла указать в php заголовок или что-то другое?
Мой код:
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">

<title>Example Json</title>
<style>
body {
  font-family: sans-serif;
  
}
#output{background-color:rgba(194,194,194,0.6);position:fixed;top:15px;right:115px;z-index:2;} 

</style>

</head>

<body>

<div id="output">
<strong>true</strong>
</div>

 <div id="tree"></div>


<script>
var bool = false;
var Index1 = 0;
var jsontent;

var bool = false;


var posts;


const recursiveList = ((ul, li, data, color = {"current" : "#767474", "wait" : "#E51012", "ok" : "#1DDD32"}) => {
            const html = Object.entries(data).map(([key, value]) => {
                const item = li.cloneNode();
                item.textContent = `[${key}]`;
                if(key === "status") item.style.backgroundColor = color[value];
                if(key === "photo") color = {"current" : "#808080", "wait" : "#FF0000", "ok" : "#00FF00"};
                value = (typeof value === "object") ? recursiveList(value, color) : ` ${value}`;
                item.append(value);
                return item;
            });
            const list = ul.cloneNode();
            list.append(...html);
            return list;
        }).bind(null, document.createElement("UL"), document.createElement("li"));

function init()
{
  
  Index1 = -1;
  bool = true;
  setInterval(test,1000);
  
  
  
}




init();

var output = document.getElementById('output');

var i = 0;
function test()
{
    ajaxQuery();

  
}

function ajaxQuery()
{
  
      var ajaxhttp = new XMLHttpRequest();
      var url = "./data.json";
      
      ajaxhttp.open("GET",url,true);
      ajaxhttp.setRequestHeader("content-type","application/json");
      
      
      ajaxhttp.onreadystatechange = function(){
        if(ajaxhttp.readyState == 4 && ajaxhttp.status == 200){
          //console.log(ajaxhttp.responseText);
          jsontent = JSON.parse(ajaxhttp.responseText);
          
          
          
          tree.innerHTML = "";
          const html = recursiveList(jsontent);
          tree.append(html);
          
           output.innerHTML = "<strong>"+bool+"</strong> " + i +" == "+Index1;
           
           posts = jsontent["response"];
           
           if(bool)
           {
              
              switch(Index1) {
                case -1:  // if (x === 'value1')
                  posts[i].status = "current";
                  break;
               default:
                 if(posts.length-1<i)
                 {
                  i = 0;
                 }
                  if(Index1 >= posts[i].photo.length)
                  {
                    posts[i].status = "ok";
                    i++;
                    Index1 = -2; 
                  }
                  else
                  {
                    posts[i].photo[Index1].big.status = "ok";
                  }
                  if(posts[i]==undefined)
                  {
                    bool = false;
                  }
                  break;
                
            
            }
              jsontent["response"] =  posts;
              
              const jsonString = JSON.stringify(jsontent);
              const xhr = new XMLHttpRequest();
              xhr.open("POST",'receive.php');
              xhr.setRequestHeader("Content-Type","application/json");
              xhr.send(jsonString);  
              Index1++;
           }
        }
      }
      ajaxhttp.send();
}
</script>
</body>
</html>

Код php:
<?php
$requestPayload = file_get_contents("php://input");
$object = json_decode($requestPayload,true);
$myFile = "data.json";
file_put_contents($myFile,$requestPayload);
?>


Прикладываю также исходники:
ex1.zip
Ответить с цитированием
  #2 (permalink)  
Старый 19.08.2022, 13:53
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,068

Olga27,
может выкинуть setInterval и забыть об этом методе навсегда, а запускать запрос через setTimeout, когда придёт ответ с сервера.
Ответить с цитированием
  #3 (permalink)  
Старый 19.08.2022, 13:53
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,723

У вас просто файлик кешируется, либо отключите кеширование вовсе, либо сделайте так, чтобы клиент загружал новую версию файла, если он изменился (почитайте про etag).

p.s. код php - моё почтение.
Ответить с цитированием
  #4 (permalink)  
Старый 19.08.2022, 15:37
Аспирант
Отправить личное сообщение для Olga27 Посмотреть профиль Найти все сообщения от Olga27
 
Регистрация: 10.06.2021
Сообщений: 49

Я не знаю в чем дело по прежнему, не работает в режиме реального времени, код setInterval я заменила на setTimeout, как советовали выше.

Вот пример:
function init()
{
  
  Index1 = -1;
  bool = true;
  
  var timer = setTimeout(function ajaxQuery(){
    
  
      var ajaxhttp = new XMLHttpRequest();
      var url = "./data.json";
      
      ajaxhttp.open("GET",url,true);
      ajaxhttp.setRequestHeader("content-type","application/json");
      
      
      ajaxhttp.onreadystatechange = function(){
        if(ajaxhttp.readyState == 4 && ajaxhttp.status == 200){
          //console.log(ajaxhttp.responseText);
          jsontent = JSON.parse(ajaxhttp.responseText);
          
          
          
          tree.innerHTML = "";
          const html = recursiveList(jsontent);
          tree.append(html);
          
           output.innerHTML = "<strong>"+bool+"</strong> " + i +" == "+Index1;
           
           posts = jsontent["response"];
           
           if(bool)
           {
              
              switch(Index1) {
                case -1:  // if (x === 'value1')
                  posts[i].status = "current";
                  break;
               default:
                 if(posts.length-1<i)
                 {
                  i = 0;
                 }
                  if(Index1 >= posts[i].photo.length)
                  {
                    posts[i].status = "ok";
                    i++;
                    Index1 = -2; 
                  }
                  else
                  {
                    posts[i].photo[Index1].big.status = "ok";
                  }
                  if(posts[i]==undefined)
                  {
                    bool = false;
                  }
                  break;
                
            
            }
              jsontent["response"] =  posts;
              
              const jsonString = JSON.stringify(jsontent);
              const xhr = new XMLHttpRequest();
              xhr.open("POST",'receive.php');
              xhr.setRequestHeader("Content-Type","application/json");
              xhr.send(jsonString);  
              Index1++;
           }
        }
      }
      
      ajaxhttp.send();
      setTimeout(ajaxQuery,1000);

  },1000);
  
  //setInterval(test,1000);
  
  
  
}

Также php файл я тоже изменила:
<?php
$myFile = "data.json";
$last_modified  = filemtime( $myFile );

$modified_since = ( isset( $_SERVER["HTTP_IF_MODIFIED_SINCE"] ) ? strtotime( $_SERVER["HTTP_IF_MODIFIED_SINCE"] ) : false );
$etagHeader     = ( isset( $_SERVER["HTTP_IF_NONE_MATCH"] ) ? trim( $_SERVER["HTTP_IF_NONE_MATCH"] ) : false );

 


$requestPayload = file_get_contents("php://input");
$object = json_decode($requestPayload,true);




  $etag     = sprintf( '"%s-%s"', $last_modified, md5( $myFile ) );


  header( "Last-Modified: ".gmdate( "D, d M Y H:i:s", $last_modified )." GMT" );

  header( "Etag: ".$etag );


  if ( (int)$modified_since === (int)$last_modified && $etag === $etagHeader ) {
    header( "HTTP/1.1 304 Not Modified" );
    exit;
  }


file_put_contents($myFile,$requestPayload);

?>
Ответить с цитированием
  #5 (permalink)  
Старый 19.08.2022, 17:41
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

const url = `полный веб путь к файлу data.json?v=${performance.now()}`;
Ответить с цитированием
  #6 (permalink)  
Старый 19.08.2022, 18:50
Профессор
Отправить личное сообщение для Nexus Посмотреть профиль Найти все сообщения от Nexus
 
Регистрация: 04.12.2012
Сообщений: 3,723

Сообщение от Olga27
Также php файл я тоже изменила
Вы же наверняка изменили receive.php, я прав?
Вам нужно добавить etag к вашему data.json файлу, а не к файлу, который принимает post-запросы.
Ответить с цитированием
  #7 (permalink)  
Старый 19.08.2022, 19:52
Аспирант
Отправить личное сообщение для Olga27 Посмотреть профиль Найти все сообщения от Olga27
 
Регистрация: 10.06.2021
Сообщений: 49

Цитата:
Вы же наверняка изменили receive.php, я прав?
Nexus, Ничего я не меняла файл выше php, предоставлен как есть, т.е. имя файла "data.json".
<?php
$myFile = "data.json";
$last_modified  = filemtime( $myFile );
....
Ответить с цитированием
  #8 (permalink)  
Старый 19.08.2022, 22:07
Аспирант
Отправить личное сообщение для Olga27 Посмотреть профиль Найти все сообщения от Olga27
 
Регистрация: 10.06.2021
Сообщений: 49

Цитата:
У вас просто файлик кешируется, либо отключите кеширование вовсе
Подскажите, как отключить кэш
Ответить с цитированием
  #9 (permalink)  
Старый 19.08.2022, 23:06
Аватар для Vlasenko Fedor
Профессор
Отправить личное сообщение для Vlasenko Fedor Посмотреть профиль Найти все сообщения от Vlasenko Fedor
 
Регистрация: 13.03.2013
Сообщений: 1,572

Сообщение от Olga27
Подскажите, как отключить кэш
const url = `полный веб путь к файлу data.json?v=${performance.now()}`;

Ответ уже написал. Каждый раз запрашиваем новый урл с разными параметрами. Ни браузер, ни сервера кешировать запросы не будут
добавьте любой рандомный параметр к запросу как в примере
Ответить с цитированием
  #10 (permalink)  
Старый 20.08.2022, 11:03
Аспирант
Отправить личное сообщение для Olga27 Посмотреть профиль Найти все сообщения от Olga27
 
Регистрация: 10.06.2021
Сообщений: 49

Не знаю, как это работает, но есть предположение. Возможно получение json файла напрямую происходит быстрее, чем получение json-файла через php обработчик.

Получаю json файл и отправляю его на рhp для записи, в итоге php не успевает выполнить скрипт и json снова вызывается со старыми данными, поэтому ничего не работает. Вообщем я сделала вызов и запись json через php. Теперь работает, а все остальные варианты нет:

function file_exists(url1)
{
  var text = "";
   $.get(url1)
      .done(function() { 
         
         $('#flag').text("true");
      }).fail(function() { 
          //text = "Файл не существует";
         $('#flag').text("false");
        
    });
  

}



function init()
{
  
  Index1 = -1;
  bool = true;
  
  var timer = setTimeout(function ajaxQuery(){
    
  
      var ajaxhttp = new XMLHttpRequest();
     // var url = 'http://3json_example.su/data.json?v=${performance.now()}';
      
      //file_exists(url);
      
      
      
      ajaxhttp.open("POST","http://3json_example.su/ex.php", true);
     
      
      
      ajaxhttp.onreadystatechange = function(){
        if(ajaxhttp.readyState == 4 && ajaxhttp.status == 200){
          //console.log(ajaxhttp.responseText);
          jsontent = JSON.parse(ajaxhttp.responseText);
          
          
          
          
          
          tree.innerHTML = "";
          const html = recursiveList(jsontent);
          tree.append(html);
          
           output.innerHTML = "<strong>"+bool+"</strong> " + i +" == "+Index1;
           
           posts = jsontent["response"];
           
           if(bool)
           {
              
              switch(Index1) {
                case -1:  // if (x === 'value1')
                  posts[i].status = "current";
                  break;
               default:
                 if(posts.length-1<i)
                 {
                  i = 0;
                 }
                  if(Index1 >= posts[i].photo.length)
                  {
                    posts[i].status = "ok";
                    i++;
                    Index1 = -2; 
                  }
                  else
                  {
                    posts[i].photo[Index1].big.status = "ok";
                  }
                  if(posts[i]==undefined)
                  {
                    bool = false;
                  }
                  break;
                
            
            }
            console.log(posts);
              jsontent["response"] =  posts;
              
              const jsonString = JSON.stringify(jsontent);
              const xhr = new XMLHttpRequest();
              xhr.open("POST",'receive.php');
              xhr.setRequestHeader("Content-Type","application/json");
              xhr.send(jsonString);  
              Index1++;
           }
        }
      }
      
      ajaxhttp.send();
      setTimeout(ajaxQuery,1000);

  },1000);
  
  //setInterval(test,1000);
  
  
  
}

Файл ex.php
<?php

$last_modified  = filemtime( __FILE__ );

$modified_since = ( isset( $_SERVER["HTTP_IF_MODIFIED_SINCE"] ) ? strtotime( $_SERVER["HTTP_IF_MODIFIED_SINCE"] ) : false );
$etagHeader     = ( isset( $_SERVER["HTTP_IF_NONE_MATCH"] ) ? trim( $_SERVER["HTTP_IF_NONE_MATCH"] ) : false );

 




$data = file_get_contents("data.json");


  $etag     = sprintf( '"%s-%s"', $last_modified, md5( $data ) );


  header( "Last-Modified: ".gmdate( "D, d M Y H:i:s", $last_modified )." GMT" );
  header("Content-Type: text/html; charset=utf-8");
  header( "Etag: ".$etag );


  if ( (int)$modified_since === (int)$last_modified && $etag === $etagHeader ) {
    header( "HTTP/1.1 304 Not Modified" );
    exit;
  }
echo $data;

?>

P.S. Хотя я протестировала во всех браузерах, через некоторое время еще раз протестирую чтобы убедиться, что все работает.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Dreamweaver CS5.5 и ООП. Не выводит подсказки методов. Как можно исправить? jsuse Общие вопросы Javascript 3 23.03.2012 19:57
Как создать bodyclick код royksopp Общие вопросы Javascript 8 14.10.2011 16:39
Как получит ссылку на элемент внутри которого запустили JS код? aRpi Events/DOM/Window 20 02.10.2011 13:36
.mouseover тормозит в Mozilla. Как исправить? denisOgr jQuery 1 30.08.2011 15:13
Как правильно прописать свой код в .js Всеми_Любимый Элементы интерфейса 6 23.02.2010 21:34