Асинхронна страница

garnet

Well-Known Member
Имам един питон скрипт, който изписва 10 неща всяко едно през различно време, да кажем всичко за 5 мин.
Ако го извикам през gеt с cgi от хтмл страница, виждам бяла страница за 5 мин и след това всичкия текст.

Как се прави (с коя технология) да може някъде по страницата да виждам текста в момента на появявянето му без да презареждам?
С ajax не става (или не го правя ОК) пак виждам всичко накуп.

Това ми е хтмл-а:
Код:
<!DOCTYPE html>
<html>
<body>

<div id="demo">
<h1>The XMLHttpRequest Object</h1>
<button type="button" onclick="loadDoc()">Change Content</button>
</div>

<script>
function loadDoc() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("demo").innerHTML =
      this.responseText;
        }
  };
  xhttp.open("GET", "https://localhost/PythonApp/index.py", true);
  xhttp.send();
}
</script>

</body>
</html>
 
Ajax с таймоут на Х секунди?
Алтернативен вариант ти е sockets (напр. socket.io)
 
Както казах идея си нямам. Малко код за проба?
 
Нещо ей такова:

Код:
function worker() {
        type: 'post',
        url: 'https.....',
        success:function(data){
            document.getElementById("demo").innerHTML = data;
        },
        complete: function() {
            setTimeout(worker, 5000);
        }

 }();

POST от ajax се вижда като GET от другата страна.
5000 са 5 секунди, през толкова ще се изпълнва функцията.
Нямам никаква идея дали не изпускам нещо, може и да не работи само с копи/пейст. Не съм тествал.

ПС. Ако скрипта изплюва по отделно инфтормацията а не я добавя към това, което вече е изплюл:

Код:
document.getElementById("demo").innerHTML += data;
 
Технически е възможно http заявка да се получава на части:
https://en.wikipedia.org/wiki/Chunked_transfer_encoding
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Transfer-Encoding

Ако сървъра отговаря по този "chunked" начин, можеш да пробваш да получиш частичния отговор с readyState == 3 вместо 4. Но за 5 мин едва ли е най-добрата идея да се прави по този начин, обикновено http заявките се случват възможно най-бързо. Предполагам зависи от това колко клиенти ще зареждат това нещо. Ако е да кажем някаква администраторска страница... става, няма лошо. Ама ако ще се обработват стотици и хиляди заявки, едва ли е добра идея.

Можеш естествено периодично да пращаш заявки дето да проверяват дали има промяна, през 10 сек да речем. И естествено другия вариант е със сокети, както беше предложено по-горе.
 
Имам чувството, че нещо се бъркаш: в Inspect element в таба network виж колко заявки има - една или много? Отвари network и рефрешни
loadDoc()- трябва да се вика 10 пъти, за 10 завки. Явно твоя скрип, прави всички 10 неща и като е готов ги праща на една завка.
 
Мисля че така е с jQuery.

Код:
// вараинт 1
var ajaxurl = "https://localhost/PythonApp/index.py";
var action = 'action'; // променлива параметур https://localhost/PythonApp/index.py?action=action
// Примерно ако скрипта прави различн неща, 1,2,3.. да ми казваш какво да прави
// var action = '1' ;
var posting = jQuery.post( ajaxurl, { "action": action  } );
   posting.done(function( data ) {
   jQuery("#demo").append(data);
});

Код:
// вараинт 2 - това преди го ползвайх да паща html, които е от WP html редактора
var data = 'Някакъв тект за пращане';
var ajaxurl = "https://localhost/PythonApp/index.py";
   jQuery.ajax({
       type: "POST",
       url: ajaxurl,
       cache: false,
       contentType: false,
       processData: false,
       dataType: 'text',
       data:  data,
           success: function (result) {
               jQuery("#demo").html(message);
            },
        error: function () {
            alert("error");
        }
});
 
@garnet реално уеб сървъра ти връща резултата когато Питоня изпълни всичко.

Трябва да промениш логиката. Варианти много могат да се измислят въпроса е какво точно е задачата да се намери оптималното решение.

Със сокети ще стане, но струва ли си? Кой знае от този код който си дал по скоро не.

:: офтопик ::
POST от ajax се вижда като GET от другата страна.

Епик глупост! @Victor R прочети малко повече преди да пишеш такива неща и да заблуждаваш незнаещите.
 
Питоня изкарва съобщения в конзолата му когато изпълни определена част от задачата. И да уеб сървъра връща всичко на куп. Въпроса е може ли да се направи да връща съобщенията към веб страницата в момента, в който се случват?
Т.е. аз не знам как да стане.

Това е един опростен питон:

Код:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-

# enable debugging
import cgitb, time
cgitb.enable()

print "Content-Type: text/plain;charset=utf-8"
print

for i in range(5):
    print i
    time.sleep(0.5)


@garnet реално уеб сървъра ти връща резултата когато Питоня изпълни всичко.

Трябва да промениш логиката. Варианти много могат да се измислят въпроса е какво точно е задачата да се намери оптималното решение.

Със сокети ще стане, но струва ли си? Кой знае от този код който си дал по скоро не.

:: офтопик ::


Епик глупост! @Victor R прочети малко повече преди да пишеш такива неща и да заблуждаваш незнаещите.
 
Не, за това ти трябва javascript има и други алтернативи като elm, clojure ама те пак компилират до дж-с. Демек искаш ли нещо да се джурка по браузъра дж-с. Вече имплементацията на аякс и/или сокет си е решение за проекта. Сокета е супер за малки пакети тъй като е по-бърз от хттп заявка. Също така със сокета можеш да пушваш от страната на сървъра, докато с аяксо ще пишеш гламави тайминг функции с голям процент празни резултати. Обаче да рендираш цяла страница да кажем с реакт или вюе си е за предпочитане аякс и апи отзад (питон, джаба, кобра или квото ти е кеф да пишеш бекенда).
 
@garnet след всеки print добави sys.stdout.flush() (мисля че в sys беше :))
В JS направи следното:

Код:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'Път-до-питоня', true);
xhr.send(null);
xhr.onreadystatechange = function() {
if (xhr.status == 200) {
if (xhr.readyState == XMLHttpRequest.LOADING){
//моментните тъпотии :Д
}
if (xhr.readyState == XMLHttpRequest.DONE){
//край
}
}
}

Само трябва да прочетеш да видиш как да изчистиш буфера от питоня за да не се случи в html елемента следното съдържание:
Итерация 1
Итерация 1 Итареция 2
Итерация 1 Итареция 2 Итареция 3

Тоест преди да output-неш чистиш всичко.
 

Горе