2010-10-21 3 views
5

Verileri döndüren bir PHP betiğine XMLHttpRequest çalıştırmak için javascript kullanıyorum. Temel olarak, kullanıcıya veri alma ve alma sürecini gösteren bir ilerleme çubuğu (bir eğirme çemberi veya bir şey yerine) sağlayabilmek istiyorum. Dosya alıp alamayacağımı biliyorum, sadece içerik uzunluğu başlığını kontrol edebilirim ve bunu kullanabilirim, fakat bir senaryo söz konusu olduğunda, ne kadar veri aldığını bilmiyorsunuz. Şu anda öyle görünüyor çünkü bunaPHP Komut Dosyası'ndan XMLHttpRequest İlerlemesi Alınması

cevap "bu mümkün değil", kadar kolay olabilir. Ancak sonuç olarak: Çalışan betiğin (php) ve XMLHttpRequest'in ilerlemesini nasıl izlersiniz?

+0

bunu yapmanın bir düzine farklı yolları vardır olabilir. Bu, PHP betiğinin ne yaptığına ve ne tür bir sunucu tarafı teknolojisine sahip olduğunuza bağlıdır. Daha spesifik olabilir misin? – mellowsoon

+0

Komut dosyası, sorguları çalıştırıyor ve xmlhttprequest yanıt işleyicisinin geçerli sayfaya eklediği html kodu oluşturmak için verileri kullanıyor. – Evan4623

cevap

1

Başımın üstünden 2 ajax istekleri kullanabilirsiniz. Biri işin tamamlanması için beklemek ve beklemek, diğeri ise işin ilerleyişini kontrol etmek. Çoğu tarayıcının bir seferde en az 2 ajax istekleri yapabileceğine eminim.

İşi yapan PHP betiği (Lets call it job.php) aslında işin tamamlandığı yüzdeyle $ _SESSION ['job_progress'] oturum değişkenini güncelleyebilir.

Sen job.php için ajax isteği ateşlemesi yani

<?php echo $_SESSION['job_progress']; 

İstemci tarafı, bu değeri echos (it progress.php diyelim) başka bir PHP komut dosyası var. Her 3 saniyede bir progress.php için başka bir ajax isteğiniz var. İlerleme çubuğunuzu geri dönen değerle güncellersiniz.

Ayrıca işten önce job.php isteği geri döndüğünde bunu bir ajax isteği ile de yapabilirsiniz. Sonra progress.php komut dosyasına ping yapmak için tek bir ajax isteği kullanmaya devam edebilirsiniz. Bazı tarayıcılarda

+0

Sanırım XHR ile şu ana kadar istediği bir dosyanın kaç bayt olduğunu bilmek istiyor. – GordonM

+0

@Gordon - Aynı kavram geçerlidir. – mellowsoon

+0

PHP, verilen bir bağlantı üzerinden kaç bayt gönderdiğinin bir kaydını tutmaz, bu yüzden ikinci bir bağlantıyı kullanmanın nasıl yardımcı olacağını gerçekten anlamıyorum. Çalıştırmak için uzun zaman alacak bir iş yürütme PHP yola olsaydın, iş tamamlandığında önce düşündüğü kadar süre bunu sormak için çözüm kullanabiliyorsunuz, ancak çok hızlı bir şekilde ancak sonuçlar biten işlerin durumunda Gönderilecek çok fazla veride bu yaklaşım çok işe yaramazdı. – GordonM

0

(biri için firefox), readyState 3 (yani yükleme) ile onreadystatechange böylece ilerleme indirmek mutiple kere izlenebilecektir çağrılır.

Ayrıca, bazı tarayıcılarda responseText özelliği sonucu şimdiye kadar döner içerir ve ilerlemenin bazı fikir edinmek için incelenebilir.

Ancak

, bu desteklemez (daha sonra hakkında emin değil, en azından IE7 için,) Internet Explorer ve ben de Yalnızca IE onreadystatechange kez çağrıları duymuş readyState 3. için responseText veya responseBody sorgulamak için bir hatadır ReadyState 3 ile amacınız için oldukça işe yaramıyor, ama test etmenizi öneririm.

0

Bir oturum oluşturun. (Muhtemelen, zaten bir tane var). İşleme başlamasını istediğinde, sorgu için bir UID oluşturun. Sorgu ilerledikçe

Mağaza yerde (dosyadaki veritabanında, vb) sunucunun SID + UID ile birlikte bir ilerleme olarak.

SID + UID ile ilerlemeyi sorgulamak için zamanlayıcıda ikinci bir ajax isteği kullanın.

Yalnızca UID ile alabilirsiniz *

, muhtemelen, ama aynı zamanda kullanıcı/oturumda tarafından görevleri izlemek ne zaman daha yönetilebilir olmasını buldum. Firefox kullanıyorsanız (ve IE dışındaki oldukça emin diğer birçok tarayıcılar değilim) ise

2

sonra gerçekten de bir XHR operasyon sırasında aktarıldıktan ne kadar veri rapor etmenin bir yolu yoktur. Söz konusu işlem doğru başlığı gönderirse, indirilen verilerin yüzdesini hesaplamak için bu bilgiyi kullanmak oldukça kolaydır.

yıllar önce bir XHR operasyonda aktarılan verilerin yüzdesini belirlenmesi için bu kodu yazdım, bu yüzden o zamandan beri elde ettik deneyim kodlama yıllarca yansıtmıyor için özür dileriz. Hemen hemen kesinlikle bu şekilde yazmazdım! Yine de, onu balık tutmayı başardım ve umarım senin için kullanırım. Bu yazıldığı anda

, IE7 mevcut Explorer'ın son sürümü olduğunu ve dolayısıyla bu IE altında başlatılıyor önlemek için kodu içeren ben, kod bu işe yaramadı hatırlıyorum. Bu kodu hiçbir zaman sürüm 8 veya sürüm 9'un beta sürümünde denemedim ve gerçekten bu sürümlerde de çalışabilir, ancak bunun için kefil olamaz. Eğer IE'nin yeni bir sürümünde çalışıyorsanız, lütfen bana bildirin!

Daha önce kodu çok uzun olan bir kod aralığı oluşturmak için (bir ajax isteğini başlatmadan önce çalıştırmak istediğiniz kod için bir geri arama jQuery kodu) beforeSend'de kod çalıştırarak çalışır (kodda 50 milisaniye koydum) Sık sık 200 milisaniye hala bol olmalı ve sisteme daha az zorlanmalıdır. Aralık zamanlayıcısı her tetiklendiğinde, XHR isteğinin responseText özniteliğine bakan bir işlevi çalıştırır. ResponseText özniteliği, şimdiye kadar alınan verilerin ham metnini tutar. Length() string yöntemiyle kaç karakterin bulunduğunu sayarak, bugüne kadar kaç bayt toplandığını araştırabiliriz.

Bildiğim kadarıyla toplam verilerin yüzdesini çalışma dışarı gönderilmek üzere gibi bu sunucu tarafı kod gönderecek kaç bayt doğru sayımına sahip bir içerik uzunlukta başlığını gönderdiğini gerektirecektir. Bu sizin tarafınızdan küçük bir zekilik gerektirecektir, ancak çok zor kanıtlanmamalıdır. Doğru bir içerik uzunluğu üstbilgisi gönderirseniz, o zamana kadar alınan verilerin yüzdesini hesaplamak için kullanılır. İçerik başlığı ayarlamazsanız, o zamana kadar alınan veri miktarı görüntülenir.

<script type="text/javascript"> 
$.ajax ({ 
    beforeSend : function (thisXHR) 
    { 
     // IE doesn't support responseText access in interactive mode 
     if (!$.browser.msie) 
     { 
      myTrigger = setInterval (function() 
      { 
       if (thisXHR.readyState > 2) 
       // When there is partial data available use it to determine how much of the document is downloaded 
       { 
        var dlBytes = thisXHR.responseText.length; 
        if (totalBytes == -1) 
         totalBytes = thisXHR.getResponseHeader ('Content-length'); 
        (totalBytes > 0)? 
         $('#progress').html (Math.round ((dlBytes/totalBytes) * 100) + "%"): 
         $('#progress').html (Math.round (dlBytes/1024) + "K"); 
       } 
      }, 50); // Check the status every 50 miliseconds 
     } 
    }, 
    complete : function() 
    { 
     // Kill the download progress polling timer 
     if (myTrigger) 
      clearInterval (myTrigger); 
    } 
}); 
</script>