Autor Zpráva
mandel99
Profil *
zdravím mám problém s kódem už opravdu nevím kde může být chyba.. ale řešení
bude určitě triviální.. jen mě teď vůbec nic nenapadá.. V poli mám generované
url na soubory, pokud se splní podmínka vytvoří se z url odkaz a do názvu odkazu
chci přidat velikost souboru bohužel vše končí pouze slovem Undefined.. pokud
ale zkusím zobrazit velikost soboru v konzoli tak to normálně funguje.. no to
je asi vše přidávám script:

var getfilesize = function (fileurl, responseHandler) {
xhr = new XMLHttpRequest();
xhr.open('HEAD', fileurl, true);
xhr.onreadystatechange = responseHandler;
xhr.send(null);
xhr.close;
}

function responseHandler() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.getResponseHeader("Content-Length"));
var filesize = this.getResponseHeader("Content-Length");
return this.getResponseHeader("Content-Length");
}
}
if (temp == '2') {
var url = odkazy + '&title=' + generate;
link += '<a href="' + url + '">' + getfilesize(url, responseHandler) +
'</a>';
}

if (temp == '9') {
var url = odkazy + '&title=' + generate;
links += '<a href="' + url + '">' + getfilesize(url, responseHandler) +
'</a>';
}

Děkuji za každou radu

Moderátor Davex: Vkládej prosím kódy mezi značky [pre] a [/pre] (stačí kliknout na ).
scheras
Profil *
1/ Nejdříve přiřazujete hodnotu proměnné getfilesize nepojmenovanou funkcí jejíž atributem je výsledek až následně definované funkce responseHandler() -> nemusí být problém
2/ Když se odkazujete na výsledek funkce (pokud tomu teda dobře rozumím), tak jí voláte stejně jako proměnnou, tj. jako responseHandler místo responseHandler() -> nemusí být problém
3/ Ve funkci responseHandler() returnem vracíte this.getResponseHeader("Content-Length");. Proč? Vždyť o řádek výš tuto hodnotu přiřazujete proměnné filesize.
4/ Vlastně nevím, jestli vám něco z toho pomůže, jsou to věci které mě napadli při čtení kódu, ale aspoň jsem se snažil :)
_es
Profil
mandel99:
link += '<a href="' + url + '">' + getfilesize(url, responseHandler) +
No ale funkcia getfilesize nič nevracia, takže je jej návratová hodnota vždy undefined a ani nemá praktický význam, aby niečo vracala. Dáta zo servera načítavaš asynchrónne, teda s nimi môžeš pracovať až po odpovedi servera, nie predtým, musíš s vrátenými dátami pracovať v reakcii na vyvolanie udalosti onreadystatechange. Nie každý prehliadač má definovaný objekt console.
mandel99
Profil *
uf.. díky za stávající rady, ale vezmu to z jiného konce. Mám pole kde jsou v náhodném pořadí odkazy k souborům: odkazy[i]
potřebuji z nich dostat velikost souboru a do jiného pole ve stejném pořadí uložit.. nějaké rady?

_es:
console je jen pro mojí informaci (debug) script navrhuju pro google chrome takže nějaké nekompatibilita s jinými prohlížeči mě nemusí trápit (rozšíření pro chrome)

scheras:
zkoušel jsem různé hodnoty, které by případně výsledek zobrazili ( console funguje nic jiného ne )
Davex
Profil
mandel99:
Mám pole kde jsou v náhodném pořadí odkazy k souborům: odkazy[i]
potřebuji z nich dostat velikost souboru a do jiného pole ve stejném pořadí uložit..
Odpovědi s velikostmi souborů mohou dorazit v náhodném pořadí, takže by měla ukládací funkce jasně vědět cíl uložení, aby se nové pole nepomíchalo.

Nějak takto:

xhr.onreadystatechange = function() { responseHandler(polekamuložit, pozice); }

/* ... */

function responseHandler(pole, index) {
  if (this.readyState == 4 && this.status == 200) {
    console.log(this.getResponseHeader("Content-Length"));
    pole[index] = this.getResponseHeader("Content-Length");
  }
}
mandel99
Profil *
Davex:
Omlouvám se, ale už jsem nejspíš retardovanej.. nejsem mistr v javascriptu učím se tak že zkouším ( pokus / omyl ) ale tohle mi vrtá hlavou už 4 dny..
prosím nekamenujte mě.. pokud je něco špatně cokoliv prosím o radu nebo spíše o opravu..
Mám script:

for (i = 0; i < odkazy.length; i++) {
    var temp = parseInt((odkazy[i].match(/id=([0-9]*)&/);
    var getSize = new Array();

    function getfilesize (fileurl, responseHandler) {
                    
                    xhr = new XMLHttpRequest();
                    xhr.open('HEAD', fileurl, true);
                                        xhr.onreadystatechange = responseHandler;
                    xhr.send(null);
    }

    function responseHandler() {
                if (this.readyState == 4 && this.status == 200) {
                    getSize = (this.getResponseHeader("Content-Length") / (1024*1024));
                    console.log(getSize);
                        if (1000 > getSize > 100) {
                            getSize = Math.round(getSize) + ' MB';
                        } 
                        else if (getSize > 1000){
                            getSize = (getSize / 1000).toPrecision(3) + ' GB';
                        } 
                        else { getSize = getSize + ' MB';
                        }
                        console.log(getSize);
                }    
    }
    if (temp == '2') {
        var url = odkazy[i] + '&title=' + title1;
        link += '<a href="' + url + '">' + getfilesize(url, responseHandler) + '</a>';
    }
    
    if (temp == '9') {
        var url = odkazy[i] + '&title=' + title2;
        link += '<a href="' + url + '">' + getfilesize(url, responseHandler) + '</a>';
}
}
Davex
Profil
Především bude nutné zcela pochopit základní princip AJAXu.
a) je asynchronní
b) v okamžiku odeslání požadavku není znám výsledek a ze serveru nejsou přečtena žádná data
c) výsledek má k dispozici až callback funkce (responseHandler), která s ním teprve může něco udělat (třeba uložit na vhodnou pozici do pole)
d) výsledky nejsou k dispozici hned, ale nějaký čas to trvá, callback funkce může výsledky uložit až po skončení volajícího skriptu

Definice funkcí a pole velikostí přesuň mimo cyklus for, aby se nepřepisovalo při každém opakování.
mandel99
Profil *
Davex
Když to přesunu mimo cyklus for tak se vrací undefined nemůžu brát z podmínky url...
stejně tak když si dám mimo for console.log(odkazy[i]); vrací se undefined už opravdu nevím co s tím už jsem se do toho zamotal..
Davex
Profil
Nejsem JavaScriptař, takže bych si vzal Chamurappiho funkci pro AJAX a upravil na

function nacti(url, callback)
{
  var xhr = window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : new XMLHttpRequest();
  xhr.open("HEAD", url, true);
  xhr.onreadystatechange = function()
  {
    if(xhr.readyState == 4)
      callback(xhr);
  };
  xhr.send("");
}

Pak bych si v cyklu spustil dotazy na velikosti souborů. Při tom bych zjistil, že je stále stejný index i a musel bych si prostudovat lexikální uzávěry. Vyšlo by mi něco takového:

var odkazy = [ "soubor1.html", "soubor2.html", "atd" ];
var getSize = [];

for (var i in odkazy) {
 (function(idx) {
    nacti(odkazy[idx], function(xhr) {
      getSize[idx] = xhr.getResponseHeader("Content-Length");
      if (odkazy.length == getSize.length) {
        // hotovo, zavolám funkci pro výpis jmen souborů a velikostí
      }
    });
  })(i);
};
mandel99
Profil *
Davex:
tak jsem to dal nějak dohromady ještě to převést do mého řešení.. :
http://jsfiddle.net/gMQ7b/
mandel99
Profil *
Davex:
bohužel mám problém s odkazy.. všechny je mám v odkazy[i]
protože nejdřív si uložím odkazy : var odkazy = [ "soubor1.html", "soubor2.html", "atd" ];
potom je proženu přes for kde je přes unescape ještě upravuji.. zkoušel jsem odkazy[i] spojit do obyčejného pole přes join ale akrorát to vyhodilo tohle:
Object has no method 'join' TypeError: Object has no method 'join'
nějaká rada?

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: