Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: Latin1 HTML-sivun lataus AJAXilla

Sivun loppuun

tsuriga [31.05.2011 11:54:42]

#

Mitenkähän saisin

  1. ladattua kokonaisen HTML-sivun AJAXilla siten, että sivulla säilyisi oikea merkistö
  2. muodostettua dokumentille DOMin ja kohdennettua tähän hakuja (getX / XPath, mikä tahansa kelpaa)

Kyseessä on GM-userscripti, jota ajan Operassa. Funktiot ovat Prototypen Class olion sisällä. Palvelin sylkee ISO-8859-1 -sivuja. En voi muuttaa palvelimen asetuksia. Testimielessä.

Kokeiltu merkistöongelmaan

Kokeiltu dokumentinmuodostusongelmaan

Evaluate kyllä palauttaa XPathResultin, mutta iterateNext ja doc.getElementById palauttavat molemmat nullia.

Koodit

Prototypellä

new Ajax.Request(e.element().readAttribute('href'), {
    method: 'get',
    encoding: 'iso-8859-1',

    onSuccess: function(response) {
        var html = response.responseText,
            contentStart = html.lastIndexOf('id="alkuid"');
        contentDiv.update(html.substring(
            contentStart + 13,
            html.lastIndexOf('id="loppuid"') - 13
        ));
    },

    onFailure: function(response) {
        contentDiv.update('<strong>Sisällön lataaminen epäonnistui.</strong>');
    }
});

Natiivisti

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = updateContentDiv;

function updateContentDiv() {
    if (xhr.readyState === 4) {
        if (xhr.status === 200) {
            var html = xhr.responseText,
                contentStart = html.lastIndexOf('id="alkuid"');
            contentDiv.update(html.substring(
                contentStart + 13,
                html.lastIndexOf('id="loppuid"') - 13
            ));
        } else {
            contentDiv.update('<strong>Sisällön lataaminen epäonnistui</strong>');
        }
    }
}

xhr.open('GET', e.element().readAttribute('href'));
xhr.setRequestHeader('Content-Type', 'text/html; charset=iso-8859-1');
xhr.send();

Kuriositeetti: Opera päätti ruveta pätkäisemään GM-userscriptin lopusta pois merkkejä kun lisäsin luokkaan tuon ajax-metodin, piti padata loppuun kommentteja :o. Tarkemmin kun testailin, niin näytti tekevän tuota, kun koodissa on riittävän monta sisäkkäistä blokkia tmv., eikä vaikuttanut vaikka koodi oli kommenttien sisällä, wtf.

GM ei näyttäisi pääsevän näköjään ollenkaan käsiksi sivun alkuperäisiin olioihin, eikä Prototypen lataaminen requirellakaan onnistu (eri versiot heittävät eri ongelmia, mistä kiitos kuuluu luultavasti GM:n astetta tiukemmalle suorituskontekstille), joten enpähän testaile sitten sitäkään, onko vika selaimessa. Pitää kokeilla Chromella, kunhan jaksaa taas tapella.

Metabolix [31.05.2011 12:50:30]

#

Merkistöongelmaan

En ota kantaa GM-puoleen, mutta JS:n tekstit ovat Unicodea, Prototype ei vaikuta tähän, XHR:n encoding vaikuttaa vain lähtevään dataan, ja sivun tai JS-tiedoston merkistökään ei käytännössä paina kuin tiedostossa olevien tekstien verran.

XHR-vastauksen pitäisi muuttua tekstiksi ihan HTTP-otsikossa olevan merkistön mukaan. Teinkin tästä pienen testin, ja kaikki näyttää toimivan ihan sääntöjen mukaan paitsi jos palvelin ei ilmoita merkistöä! Eli jos palvelimelta tulee pelkkä "Content-Type: text/html", merkistö näyttäisi maagisesti menevän UTF-8:ksi, jolloin responseText sisältää U+FFFD-merkkejä. Tässä vaiheessa encode-decode-kikka on luonnollisesti jo myöhässä.

Ehdotan siis seuraavaksi kokeiluksi, että lähetät palvelimelta selvän merkistötiedon.

header("Content-Type: text/html; charset=ISO-8859-1");

Dokumentinmuodostusongelmaan

Varmasti tunnet itse datasi paremmin, mutta onkohan tuo -13 kuitenkaan oikein tekstin loppuindeksissä?

Helppo purkkaratkaisu itse ongelmaan voisi olla, että luot vain sivun loppuun näkymättömän divin ja dumppaat HTML:n sinne. Sittenhän käytössä ovat täsmälleen samat hakuvälineet kuin sivulla muutenkin.

jQueryssa taitaisi onnistua myös tuo ensimmäinen ideasi, $(koodi). En sitten tiedä, toimiiko tuosta välttämättä hakeminen.

tsuriga [31.05.2011 13:11:13]

#

Yritin tässä siis hakea Putkan alasivuja kehittäessäni lisätoimintoja Putkaan, "alkuid" on oikeasti "sisalto" ja "loppuid" "alapalkki". Jos tän nyt joskus saa toimimaan niin tutkin luonnollisesti lisääkö tämä kaistankulutusta, ts. ohittaako välimuistituksen (ei pitäisi?). En siis pääse vaikuttamaan palvelimen lähettämään dataan :). Ihan hyvä idea tuo diviin puuppaus, tattis.

Metabolix [31.05.2011 13:13:56]

#

Ahaa, no toimiiko nyt? :)

tsuriga [31.05.2011 14:19:25]

#

Toimii, kiitos :). Kokeilin myös tuota diviin upottamista, mutta DOM-puun luominen kokonaiselle dokumentille on sen verran raskasta, että tuosta aiheutui huomattava nopeusero. Myöskin luodun divin poistamisessa oli ongelmia (sille ei löytynyt parenttia. Ehkäpä, koska selain ei ollut ehtinyt muodostamaan DOM-puuta?), joten käytän suosiolla tuota substr-purkkaa. Kiitos myös merkistöselvityksistä, tuntuu taas piirun verran viisammalta. Jonkun hakutuloksen mukaan ECMAScriptin suositeltu koodaus olisi UTF-16, huhhuh.

Metabolix [31.05.2011 14:33:46]

#

Kyllähän sillä divillä pitäisi parentNode olla? Ainakin minulla toimii ihan hyvin tämä rimpsu:

var div = document.createElement("div");
document.body.appendChild(div);
div.innerHTML = "<a id='testi' href='#abc'>abc</a>";
alert(document.getElementById("testi").href);
div.parentNode.removeChild(div);

Grez [31.05.2011 14:34:59]

#

tsuriga kirjoitti:

Jonkun hakutuloksen mukaan ECMAScriptin suositeltu koodaus olisi UTF-16, huhhuh.

Mitä tarkoitat tuolla suositellulla koodauksella? Uskoisin, että skriptin muuttujat ainakin sisäisesti onkin koodattu UTF16:lla enkä pitäisi sitä mitenkään ihmeellisenä.

tsuriga [31.05.2011 15:24:56]

#

Virhe tulikin siitä, kun ylikirjoitin uuden divin epähuomiossa updatella, ei liene yllätys ettei divillä ole silloin enää parenttia. Diviin puuppamisessa esiintyy kumminkin hitausongelmaa siirryttäessä tietyltä sivulta toiselle, esim. tästä keskustelusta Ohjeet-sivulle. Substring-purkalla tätä ongelmaa ei ole.

Debuggaus on tällä hieman mystistä, Dragonflyn virhevälilehdelle ei tulostu virheitä ollenkaan, vaan pitäs muistaa ottaa break on error pois skriptivälilehdeltä ja skrollata koodia, tai sitten kattella suoraan Operan virhekonsolia.

Njoo, sisäiseen koodaukseenhan tuolla viitattiin, luin huolimattomasti.

Putkan palvain kehottaa näköjään lataamaan aina uusiksi. AJAX lisää kyllä Prototypellä kaksi ylimääräistä headeria itse sivurequestiin, mutta... Dragonfly näyttää AJAXia käytettäessä vain tuon itse sivun hakemisen. Onko siis niin, että Opera ei yritä hakea sivun resursseja, vaikka lisään koko sivun DOM-puuhun? Koska tällöin kaistansäästöä tulisi selvästi, kun ei tarvitse olla pyytelemässä joka sivupyynnöllä resursseja, jotka eivät vaihdu kuitenkaan (palvelin lähettää 304:sta). Ja jos DOM-puuhun pujottaminen tuottaa resurssihakuja niin pitääkö tässä taas palata substring-purkkaan?

Metabolix [31.05.2011 16:06:28]

#

Pitäisin mahdollisena, että selain aloittaa resurssien lataamisen vasta, kun JS on suoritettu. Tuossa kuitenkin poimit saman tien mukaan pelkän sisällön, jolloin resursseja ei ehkä ehditä käsitellä.

Mahdollisissa substring-kikkailuissa body voisi olla varmempi kiintopiste.

tsuriga [31.05.2011 16:13:16]

#

Kunhan Putka ei vaihda id:itä tai elementtien järjestystä niin hyvin toimii :). Yritän emuloida semanttista toimintaa, jossa vaihdetaan vain muuttuva sisältö. Totta tosiaan, tällä ei päivity sivupalkki, mutta sen päänmenoksi olen suunnittellut jo muutakin.

Metabolix [31.05.2011 16:21:35]

#

Älä tee liian innokkaasti, ettei muutoksista seuraa pettymyksiä. ;P


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta