Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
radian1
Tvůrce
Avatar
radian1:26.7.2018 14:56

Ahoj, mám tento ajax:

var xhr = new XMLHttpRequest();
xhr.open("GET", "zzzzzzk.html");
xhr.send();

xhr.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
          console.log(xhr);
  }
};

do konzole se mi vypíšou metody + tam je response a responsetext

Ale když k tomu připíšu ještě responsetype:

xhr.responseType = "document";

var xhr = new XMLHttpRequest();
xhr.responseType = "document";
xhr.send();

xhr.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
          console.log(xhr);
  }
};

tak mám v konzoli u response a responseXML hodnotu null

ten dokument zzzzzzk.html je html5 stránka + se mi v každém případě zobrazí i varování
Chyba parsování XML: Neshodující se značka. Očekávána značka: </link>.
Adresa: file:///C:/User­s/****/Desktop/*******­/zzzzzzk.html
Řádek 59, sloupec 5:

Zkusil jsem: hledat, ale nemůžu najít odpověď

Chci docílit: Co dělám špatně? Jak můžu z toho vráceného dokumentu vybrat ID (nebo class) abych mohl obsah přesunout do mojí stránky z které volám ajax? Nikde sem to nemohl najít, všude jsou příklady jen z čistého souboru txt

 
Odpovědět
26.7.2018 14:56
Avatar
Jindřich Máca
Tvůrce
Avatar
Odpovídá na radian1
Jindřich Máca:26.7.2018 22:25

Ahoj, špatně děláš v první řadě to, že v tom souboru zzzzzzk.html neposíláš validní HTML, ale to asi nebude jediná chybka, které se dopouštíš. Mám dneska dobrou náladu, tak to trochu rozvedu.

1. První problém působí na pohled jako kosmetická vada na kráse, ale v důsledku může způsobovat až časově závislou chybu. Jedná se o pořadí těch příkazů. Přeci nemůžeš definovat funkci pro zpracování až potom, co už je požadavek odeslaný... Takže by to mělo vypadat spíš takhle:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
  if(xhr.readyState === 4 && xhr.status === 200) {
     console.log(xhr);
  }
};
xhr.open("GET", "zzzzzzk.html");
xhr.responseType = "document";
xhr.send();

P.S.: Nechci Tě mást, ale šlo by to udělat i jednodušeji pomocí onload eventu (viz. ukázky v odkazu níže).

2. Druhý a ten zásadní problém je, jak jsem uvedl hned na začátku, že v tom souboru zzzzzzk.html máš nevalidní HTML. V tom první příkladu, co jsi uvedl se to neprojeví, protože tam to přebíráš jako prostý text a nepokoušíš se to nijak dále zpracovat. Trochu mě pak ale zaráží ten styl, jakým jsi to podal. Napíšeš to sem jako

zobrazí i varování

a pod tím chyba jako brno

Chyba parsování XML

Jelikož jsi sem to HTML neuvedl, těžko soudit v čem přesně je problém, ale na druhou stranu v té chybě je to přesně napsané včetně čísla řádku...

Zkusil jsem: hledat, ale nemůžu najít odpověď

A zkusil jsi vůbec přečíst tu přesně definovanou chybu, kterou jsi sem zkopíroval a která je dokonce v češtině?! :-?

3. Další věc, na které ještě záleží jsou pak HTTP hlavičky s typem obsahu a kódováním, které se při parsování také mohou brát v potaz. Ale to spíš jen pro jistotu, protože bych řekl, že to nebude Tvůj problém...

Každopádně bych vřele doporučil nastudovat si https://developer.mozilla.org/…LHttpRequest, kde je vše popsáno, včetně omezení a příkladů. ;)

Jinak až se Ti to podaří, tak ten získaný objekt je typu Document, defakto stejný jako ten uložený v globální proměnné document. Můžeš s ním tedy i stejně pracovat pomocí jeho rozhraní viz. https://developer.mozilla.org/…API/Document. A pokud tyto dva chceš nějak propojovat, tak bys měl také využít příslušných metod z tohoto rozhraní, což obecně nemusí být úplně triviální. :-`

 
Nahoru Odpovědět
26.7.2018 22:25
Avatar
radian1
Tvůrce
Avatar
Odpovídá na Jindřich Máca
radian1:27.7.2018 9:26

máš pravdu že sem to měl přehodit.
Ale ten dokument html je validní, akorát tomu ajaxu se nelíbí že meta značky a br elementy nejsou uzavřeny lomítkem.
Jinej způsob než to psát s lomítkama neni?

ale pořád nevím jak můžu vybrat element
v tom mojim mám ve script toto:

var xhr = new XMLHttpRequest();
XMLHttpRequest.responseType = 'document';
xhr.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 200) {
          var data = xhr.response;
          console.log(data);
          console.log(data.title); // undefined
          var element = Document.getElementById('main'); // type error
          console.log(element);
          console.log(Document.links); // undefined
  }
};

xhr.open("GET", "zzzzzzk.html");
xhr.send();

takhle sem zkrátil ten zzzzzk.html a přidal sem tomu lomítka.

<!DOCTYPE html>
<html lang='cs'>
  <head>
    <title>ZZk</title>
    <meta charset='utf-8' />
    <meta name='author' content='' />
    <meta name='robots' content='all' />
  </head>

  <body>

<div id="wrapper">

  <header id="header" style="" class="js-Menu"></header>

  <main id="main" role="main">
    <p>Text článku</p>
  </main>

  <footer id="footer"></footer>

</div>

</body>
</html>
 
Nahoru Odpovědět
27.7.2018 9:26
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:27.7.2018 9:48

Musis se naucit googlovat.
Je to xml (dom). Neni to html. Nefunguje na to stejny js jako na html.
Muzes s tim pracovat pres childNodes, getElementByTag­Name. Ale nejde pouzit ostatni pohodlnejsi funkce.

google = js parse xml

<address>
  <street>Roble Ave</street>
  <mtfcc>S1400</mtfcc>
  <streetNumber>649</streetNumber>
  <lat>37.45127</lat>
  <lng>-122.18032</lng>
  <distance>0.04</distance>
  <postalcode>94025</postalcode>
  <placename>Menlo Park</placename>
  <adminCode2>081</adminCode2>
  <adminName2>San Mateo</adminName2>
  <adminCode1>CA</adminCode1>
  <adminName1>California</adminName1>
  <countryCode>US</countryCode>
</address>

if (window.DOMParser)
{
    parser = new DOMParser();
    xmlDoc = parser.parseFromString(txt, "text/xml");
}
else // Internet Explorer
{
    xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
    xmlDoc.async = false;
    xmlDoc.loadXML(txt);
}
// ---
//Gets house address number
xmlDoc.getElementsByTagName("streetNumber")[0].childNodes[0].nodeValue;

//Gets Street name
xmlDoc.getElementsByTagName("street")[0].childNodes[0].nodeValue;

//Gets Postal Code
xmlDoc.getElementsByTagName("postalcode")[0].childNodes[0].nodeValue;

https://andrew.stwrt.ca/…xml-parsing/

google = js xml to array

 <?xml version="1.0" encoding="iso-8859-1"?>
 <profiles>
 <profile id="1">
     <pic>images/profiles/person1/x.jpg</pic>
     <name>Joe Bloggs</name>
     <nickname>J-Bloggs</nickname>
     <age>21</age>
     <email>[email protected]</email>
     <role>Web Site Manager</role>
     <likes>
           <like1>Food</like1>
           <like2>Drink</like2>
           <like3>Computing</like3>
           <like4>Music</like4>
     </likes>
     <dislikes>
           <dislike1>Rude People</dislike1>
           <dislike2>Rude People</dislike2>
     </dislikes>
     <favwebsite>http://www.facebook.com</favwebsite>
 </profile>
</profiles>

var profiles = xml.getElementsByTagName("profile");
var arr = [];
for (var key in profiles){
    arr.push([]);
    var nodes = profiles[key].childNodes;
    for (var ele in nodes){
        if(nodes[ele]){
          arr[key].push(nodes[ele]);
        }
    }
}
console.log(arr);

https://api.jquery.com/…ry.parseXML/

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>jQuery.parseXML demo</title>
  <script src="https://code.jquery.com/jquery-1.10.2.js"></script>
</head>
<body>

<p id="someElement"></p>
<p id="anotherElement"></p>

<script>
var xml = "<rss version='2.0'><channel><title>RSS Title</title></channel></rss>",
  xmlDoc = $.parseXML( xml ),
  $xml = $( xmlDoc ),
  $title = $xml.find( "title" );

// Append "RSS Title" to #someElement
$( "#someElement" ).append( $title.text() );

// Change the title to "XML Title"
$title.text( "XML Title" );

// Append "XML Title" to #anotherElement
$( "#anotherElement" ).append( $title.text() );
</script>

</body>
</html>
 
Nahoru Odpovědět
27.7.2018 9:48
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:27.7.2018 9:52

https://www.codingforums.com/…ascript.html

XMLDocument.prototype.toArray = function()
{
        if (typeof Element.prototype.toArray == 'undefined')
        {
                Element.prototype.toArray = function()
                {
                        if (this.childElementCount)
                        {
                                this.array = new Array();
                                for (i in this.children)
                                {
                                        if (this.children[i].nodeType == 1)
                                        {
                                                this.array[this.children[i].nodeName] = this.children[i].toArray();
                                        }
                                }
                                return this.array;
                        }
                        else
                        {
                                return this.textContent;
                        }
                }
        }
        this.array = new Array();
        this.array[this.documentElement.nodeName] = this.documentElement.toArray();
        return(this.array);
}
 
Nahoru Odpovědět
27.7.2018 9:52
Avatar
radian1
Tvůrce
Avatar
radian1:27.7.2018 11:12

ok, díky

 
Nahoru Odpovědět
27.7.2018 11:12
Avatar
radian1
Tvůrce
Avatar
radian1:27.7.2018 13:08

jquery má funkci find díky kterýmu můžu hledat cokoliv, ale tady ne. Tak to asi už bude daleko lepší JSON

 
Nahoru Odpovědět
27.7.2018 13:08
Avatar

Člen
Avatar
:27.7.2018 14:23

A prečo nepoužiješ jQuery s ktorým to ide? Bez problémov, crossbrowser, na tri riadky?

 
Nahoru Odpovědět
27.7.2018 14:23
Avatar
radian1
Tvůrce
Avatar
Odpovídá na
radian1:27.7.2018 17:52

protože nemám rád rozsáhlí knížky jako je jquery a 96% věcí mám uděláno ve vanille js

 
Nahoru Odpovědět
27.7.2018 17:52
Avatar
Odpovídá na radian1
Patrik Valkovič:27.7.2018 19:06

A máš k tomu nějaký rozumný důvod?

Nahoru Odpovědět
27.7.2018 19:06
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
radian1
Tvůrce
Avatar
Odpovídá na Patrik Valkovič
radian1:28.7.2018 10:58

JS je sám o sobě rychlejší (podle vanilla-js.com) a navíc yablko vydává js kurz a já sem si řekl že to udělám čistě v js, jinak původně sem používal jQuery. JS nabízí úplně to stejný až na pár věcí.

 
Nahoru Odpovědět
28.7.2018 10:58
Avatar
radian1
Tvůrce
Avatar
radian1:10.8.2018 22:28

1. První problém působí na pohled jako kosmetická vada na kráse, ale v důsledku může způsobovat až časově závislou chybu. Jedná se o pořadí těch příkazů. Přeci nemůžeš definovat funkci pro zpracování až potom, co už je požadavek odeslaný...

A neni to náhodou jedno? Prohlížeč přece musí nejdříve proběhnout celej soubor js a načíst funkce do paměti. Do té doby než neproleze celý soubor tak přece nemůže nic spouštět nebo se pletu? Hoisting se tomu říká. Možná se pletu, ale seš si jistej že by to mohlo způsobit problémy?

 
Nahoru Odpovědět
10.8.2018 22:28
Avatar

Člen
Avatar
:10.8.2018 23:03

1. Na tom poradí nezáleží, iba musíš ten
typ nastaviť pred zavolaním send().

2. Avšak používanie XHR na nahranie HTML je problémové. Pôvodne podporoval iba XML, HTML sa pridávalo neskôr. A aj ťa to zaskočilo, pretože nepárové značky do XML nepatria.

3. Preto ak už čistý JS, tak Fetch API. Ak sa obávaš o kompatibilitu, tak plus polyfill, alebo to nechať na Babel.

4. Ale knižnice nie sú zlo. Ak šetríš bajty, nahraj si axios, malú knižnicu len na AJAX, alebo superagent, tá má prehľadnejší syntax, sám ju tiež používam. Lebo ak fetch() ešte nepoznáš, tak ako XHR s HTML, tak ťa Fetch zaskočí s CORS. A s axios nie.

Editováno 10.8.2018 23:03
 
Nahoru Odpovědět
10.8.2018 23:03
Avatar
radian1
Tvůrce
Avatar
Odpovídá na
radian1:11.8.2018 9:54

Tím typem myslíš open(get)? Tak to sem udělal tedy správně.
A co je ten onload? To je i po načtení všech obrázků?

 
Nahoru Odpovědět
11.8.2018 9:54
Avatar

Člen
Avatar
:11.8.2018 12:36

Zhrniem Ti to:

Od začiatku si žiadnu chybu v XHR nerobil. Keď si nenastavil responseType, všetko fungovalo, lebo defaultne je responseType text. Takže bolo doslova fuk čo ti prišlo v odpovedi. Akonáhle si však nastavil responseType na document, očakával sa v odpovedi platný XML dokument. A tam si urobil chybu, v HTML, nie v XHR, lebo bežné HTML nie je platné XML. V tomto zmysle, že v XML musia byť všetky značky párové, uzavreté. A tak ti to zhavarovalo hneď v head, kde sú meta či link značky nepárové. Ak totiž plánuješ HTML strojovo spracúvať, mal by si použiť XHTML zápis, takže každú nepárovú značku, čiže aj ten link, br, img a pod. uzavrieť tým koncovým lomítkom. Iný spôsob nie je, keďže si sa na to vyslovene pýtal... Nasledne ti chýbal find z jQuery, ale to problém nie je. Vrátenú odpoveď môžeš traverzovať napríklad pomocou querySelector. Avšak je ti to celé rovno nanič, lebo to aj tak nemusí fungovať. Myslím, že v Safari napríklad ti to nepôjde. Takže sa zbytočne snažíš a keďže už chceš dve veci, ajax aj traverzovanie, preto som ti navrhol jQuery, lebo sú tam tieto veci ošetrené a je to crossbrowser. Ok, odmietol si. Preto som ti potom navrhol Fetch API, lebo to Ti bude fungovať v každom novom prehliadači, je to náhrada za XHR. Jasne, nejde v starých prehliadačoch, IE je tým pádom out, ale na to sú polyfills. Alebo Babel. S fetch však skôr či neskôr narazíš na CORS. Zasa sa s tým môžeš začať trtkať ručne a hľadať ako správne nastaviť request, alebo ... použi konečne knižnicu. Správne a crossbrowser všetko ponastavovať nie je hračka, to chce väčšiu hĺbku znalostí akú máš teraz. Navyše je to však nezmysel, lebo napísať to všetko sám, univerzálnym a crossbrowser ošetreným spôsobom v konečnom dôsledku znamená, že si napíšeš knižnicu. Akurát, že vlastnú. Takže načo celé toto? Nanič. Axios, superagent a pod. Tak znie tvoje riešenie...

Neodhováram ťa však úplne. Ak na to máš čas, skúšaj. Čím viac do hĺbky budeš chápať, tým lepšie. Mal by si však vedieť, že hlavne sa používa Fetch a až ako záložné riešenie XHR. Na traverzovanie, hľadanie v odpovedi sa používa to, čo v normálnom html, napríklad querySelectorA­ll('.mojaClas­s') a áno, tým onload mysleli to, že aj window má onload event, aj img má onload event, aj xhr má onload event...

A ako posledné by si mal vedieť, že správny spôsob je nepýtať sa niekde na základy. Správny spôsob je otvoriť si na MDN dokumentáciu k príslušnej API, prejsť ju kompletne aj s príkladmi, a až keď ju naštuduješ ale aj tak ti niečo nepôjde, lebo si to napríklad zle pochopil, až potom sa pýtaš. Hlavne nie spôsobom akým to robíš teraz: zahliadol som niekde nejaké XHR a skúšam ho použiť bez toho, aby som si ho naštudoval. A nejde mi to. Kde je chyba? No kde kurva asi... :P:)

Editováno 11.8.2018 12:37
 
Nahoru Odpovědět
11.8.2018 12:36
Avatar
Jindřich Máca
Tvůrce
Avatar
Odpovídá na radian1
Jindřich Máca:11.8.2018 13:10

Uznávám, že většinou je to jedno stejně jako v tomto případě, ale pokud třeba sleduješ stav, bude se chování při jiném pořadí lišit. Příklad:

var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {console.log('XHR State: ' + xhr.readyState)};
xhr.open("GET", "test.txt");
xhr.send();

vypíše:

XHR State: 1
XHR State: 2
XHR State: 3
XHR State: 4

Když to:

var xhr = new XMLHttpRequest();
xhr.open("GET", "test.txt");
xhr.send();
xhr.onreadystatechange = function () {console.log('XHR State: ' + xhr.readyState)};

vypíše pouze:

XHR State: 2
XHR State: 3
XHR State: 4

Je to pouhý detail, ale chování je prostě jiné. :-`

P.S.: Co který stav znamená najdeš v dokumentaci - https://developer.mozilla.org/…t/readyState

Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
11.8.2018 13:10
Avatar

Člen
Avatar
Odpovídá na Jindřich Máca
:11.8.2018 13:22

Ale mňa stav v princípe nezaujíma. A jeho tiež nie. Čo on chce a nevie, že to tak ide, je napísať to takto:

var xhr = new XMLHttpRequest()

xhr.open('GET', 'page.html')
xhr.responseType = 'document'
xhr.onload = function () {
  console.dir(xhr.response.querySelectorAll('.someClass')
}
xhr.send()
Editováno 11.8.2018 13:23
 
Nahoru Odpovědět
11.8.2018 13:22
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:13.8.2018 9:59

Jeste mne napadlo, ze by mohl pouzit response = text. Pres innerHTML to vlozit do nejakeho divu s display=none a pak by s tim slo pracovat jako s html. Ale pak je mozne tam take pridat parazitni js. Tusim, ze innerHTML ma na to nejaka omezeni.

Jinak, na tom poradi pomerne zalezi. Jak pise Jindřich Máca. Send by mel byt posledni v poradi. Hlavne je mozne narazit na cross-browser komplikace.

Vladislav Ladicky - To je zrovna podobne, take muzes narazit na cross-browser komplikace. Defaultne to neni vzdy xml a vzdy utf8. Mozna ted u novejsich browseru. Lepsi je kodovani vzdy definovat. A idealne prave do xml nebo text a utf-8. Nektere browsery nemeli vubec moznost kodovani zmenit. To se vymstilo jednomu znamemu, ktery chtel posilat w1250 :)

 
Nahoru Odpovědět
13.8.2018 9:59
Avatar
radian1
Tvůrce
Avatar
Odpovídá na Peter Mlich
radian1:13.8.2018 17:04

;-) to je fakt, ale já původně přes Ajax stahoval celou stranku takže by tam byly dvě hlavičky do té doby než bych to pak celý smazal. Ale mohl bych ověřit zda jde o Ajax požadavek... Já už jsem to udělal v json. A teď když nad tím přemýšlím tak ten tvůj způsob by byl daleko jednodušší :-) než se psát s generováním jsou. Že sem na to nepřišel sám :-?

 
Nahoru Odpovědět
13.8.2018 17:04
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:14.8.2018 10:23

's generováním jsou' ???
Na to jsou funkce, v php i ve firefox js.
google = php json -> json_encode($arr)
google = js json -> JSON.parse(str); (str = request.response)

 
Nahoru Odpovědět
14.8.2018 10:23
Avatar
radian1
Tvůrce
Avatar
Odpovídá na Peter Mlich
radian1:14.8.2018 17:50

Ano, ale když vybírám třebas komentáře tak tu strukturu JSON musím napsat já. Je pravda že sem to ve výsledku udělal složitější než by to šlo.

 
Nahoru Odpovědět
14.8.2018 17:50
Avatar
Peter Mlich
Člen
Avatar
Peter Mlich:15.8.2018 15:14

Nerozumim, co znamena vybirat komentare.
Z sql vyberes data. Ta preformatujes fetchem do pole a pole zakodujes pres json_encode na string. String odeslels uzivateli pres echo do requestu. Request ot prebere jako text. Dekoduje pres parse na pole.
Tusim, jedina zaludnost je, ze nekde je treba rici, ze z toho chces pole a ne objekty. Tusim, ze to je v php pri decode, ale to tam nepotrebujes.
To bys musel ukazat kod a rici, co to ma vlastne delat a co to nedela, od ktereho radku je to spatne a tak.

https://developer.mozilla.org/…s/JSON/parse
Tady to dekoduji primo do pole, se kterym se da pracovat.

http://php.net/…n-decode.php
Tady je ta zaludnost...
assoc = When TRUE, returned objects

Example #1 json_decode() examples
<?php
$json = '{"a":1,"b":2,"c":3,"d":4,"e":5}';

var_dump(json_decode($json));
var_dump(json_decode($json, true));

?>
Editováno 15.8.2018 15:16
 
Nahoru Odpovědět
15.8.2018 15:14
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 22 zpráv z 22.