Autor Zpráva
hypot
Profil
Zdravím, chtěl bych poslat data z prohlížeče na server do souboru PHP (vložit je do pole), ale nedaří se mi to a nezbývá mi než si nechat poradit, jak to zprovoznit.
Konkrétně jde o obsah určitých částí HTML dokumentu zaslaný jako reakce na událost, ale to snad není tak důležité. Funkčnost zatím zkouším na localhostu.
Tady je můj Javascript (část z něj):
var ajax = new XMLHttpRequest;
            ajax.open("POST", "002.php");
            ajax.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
            var ajax_predmet = "predmet=" + item.firstChild.nodeValue; // (item je - na okraj - event.target)
            ajax.send(ajax_predmet)
Toto mám v pokusném souboru 002.php (zatím jen zkouším vypisovat):
if (isset($_POST["predmet"])) $obdrzene = $_POST["predmet"];
if (isset ($obdrzene)) echo $obdrzene;
// $items = [];
// array_push($items, $obdrzene)
Když ovšem načtu soubor 002.php v prohlížeči, ukáže se mi jen prázdná stránka a když v php souboru vynechám podmínky s funkcí isset, zobrazí se mi varování Notice: Undefined index: predmet in ... (atd.). Z toho hlášení soudím, že se data nepředala, ale nevím, kde je teda chyba. Každopádně podle konzole prohlížeče aspoň kontakt serveru proběhl úspěšně, takže bych spíš sázel, že mám špatně PHP kód; nicméně opravdu nevím. Děkuji za radu.
Radek9
Profil
hypot:
Když ovšem načtu soubor 002.php v prohlížeči
Počkej. Kontroluješ to, co ti ten ajax vrací? XMLHttpRequest má událost onreadystatechange, ve které dostaneš odpověď od serveru:
ajax.onreadystatechange = function () {
  if (ajax.readyState === 4 && ajax.status === 200) {
    alert(ajax.responseText)
  }
}

Je logické, že když si otevřeš tu stránku přímo v prohlížeči, tak je hodnota proměnné $_POST prázdná. V tu chvíli nic serveru neposíláš.
hypot
Profil
Radek9:
Je logické, že když si otevřeš tu stránku přímo v prohlížeči, tak je hodnota proměnné $_POST prázdná. V tu chvíli nic serveru neposíláš.

Přiznám se, že ať nad tím dumám, jak nad tím dumám, stále tomu nerozumím. Javascript mám připojený k souboru 001.php a text chci poslat do souboru 002.php (to jsem zřejmě měl uvést hned). V souboru 001.php kliknu na určitý prvek s textovým obsahem a onen textový obsah chci přenést do souboru 002.php, který by ho měl pro začátek aspoň vypsat.
Odpověď serveru jsem do Javascriptu původně nezařadil, jelikož jsem soudil, že ji k ničemu nepotřebuju, nicméně když jsem ji na radu přidal, dostal jsem jako výsledek textový obsah prvku, na který jsem klikl, což je přesně ta informace, kterou jsem chtěl přenést. Jak to tedy je - posílám něco nebo neposílám?
Keeehi
Profil
Javascriptem to posíláš. Ovšem když si v prohlížeči jen otevřeš soubor 002.php tak při tom se žádná data neposílají.
_es
Profil
hypot:
Keeehi:
Ovšem když si v prohlížeči jen otevřeš soubor 002.php tak při tom se žádná data neposílají.
A okrem toho nie je vtedy ani použitá metóda post ale get.
hypot
Profil
No jo, když člověk nechápe podstatu, je to na tom to nejhorší. :-(

Keeehi:
Ovšem když si v prohlížeči jen otevřeš soubor 002.php tak při tom se žádná data neposílají.
Samozřejmě že chápu, že kdybych měl vedle sebe předem v prohlížeči otevřené soubory 001.php a 002.php a z prvního něco odeslal ajaxem, že se to hned v tom druhém nemůže hned samo od sebe nějak magicky projevit, ale to já nedělám. Já jsem měl (respektive zatím stále mám) za to, že když z prohlížeče nejprve zašlu na server ajaxem nějaké údaje a teprve poté si od něj do prohlížeče vyžádám soubor, který má nakládat (např. je zobrazit) s odeslanými údaji, v okamžiku vyžádání toho druhého souboru (v mém případě 002.php) už server bude mít odeslané údaje k dispozici a může mi je tedy v požadované stránce poskytnout. Jenže je neposkytuje. Jak to, že je teda k dispozici nemá?

_es:
A okrem toho nie je vtedy ani použitá metóda post ale get.
Použitá nebo použitelná? Má to na něco vliv?
Keeehi
Profil
hypot:
Jak to, že je teda k dispozici nemá?
Protože to jsou dva oddělené požadavky. Každý požadavek na server je sám o sobě. HTTP je totiž bezstavový protokol. To znamená, že stav (zjednodušeně data) se nepřenášejí mezi požadavky. Když tedy pošleš na server v požadavku nějaká data, server s nimi může v rámci daného požadavku pracovat. Jakmile ale sestaví odpověď a pošle ti ji nazpět, tak všechno zapomene. Když pak tedy pošleš na server druhý požadavek (otevřeš si stránku 002.php), tak server o těch datech už dávno neví. Aby k nim měl přístup, musel by si je server v prvním požadavku někam uložit a při druhém je opět načíst. Existuje několik možností jak přenášet data mezi požadavky s různým stupněm trvanlivosti těchto dat. Ovšem pro debugování AJAXu to není potřeba.

Jak už psal Radek9 v [#2], celá odpověď ze serveru se po dokončení AJAXového požadavku bude nacházet v ajax.responseText kterou si můžeš někam vypsat. Druhou možností je použít vývojářské nástroje, které jsou vestavěné v prohlížečích. Když si je zapneš a odešleš AJAXový požadavek, tak v části Síť / Network (může se jmenovat jinak) se objeví tvůj požadavek. Po kliknutí na něj si můžeš zobrazit hlavičky, celou odpověď aniž bys ji musel v javascriptu vypisovat a spoustu dalších užitečných věcí. img.djpw.cz/sqh.gif
hypot
Profil
Keeehi:
Aby k nim měl přístup, musel by si je server v prvním požadavku někam uložit a při druhém je opět načíst.
Já už možná začínám tušit, v čem chybuju. Já jsem myslel, že obsah polí $_GET, $_POST a $_REQUEST je dostupný všem skriptům (stránkám) na stejné doméně (že jde o něco jako sessionStorage v prohlížeči); ale ono to tak asi není, že?
Radek9
Profil
hypot:
Správně. Jsou dostupné vždy jen v rámci jednoho konkrétního požadavku. V tvém případě je jeden požadavek ten ajax (tam ta data opravdu posíláš a také skutečně dostaneš odpověď) a druhý je to přímé otevření stránky. V tu chvíli mají oba požadavky rozdílná data a proto se chovají jinak.
hypot
Profil
Takže když budu chtít něco ukládat na serveru, aby to bylo přístupné odevšad, musím to uložit do souboru?
Radek9
Profil
hypot:
Stačí do $_SESSION. Ta je navíc pro každého uživatele unikátní. Soubor bys měl společný pro všechny uživatele. Otázka ale je, k čemu konkrétně to potřebuješ a jestli se to nedá vyřešit jinak.
Keeehi
Profil
hypot:
Jak jsem psal, možností je spousta. Cookie, session, soubor, databáze - to jsou asi ty nejběžnější. Ale pro ajax ani pro jeho debugging nejsou potřeba.
hypot
Profil
Je se zeptám ještě na jednu věc, která mi není jasná:
Jak jsem napsal, chtěl jsem přenést textový obsah určitých částí dokumentu na server a tam uložit do pole. V PHP jsem na uložení poslaných dat použil tento kód:
if (isset($_POST["predmet"])) $obdrzene = $_POST["predmet"];
if (!isset ($items)) $items = [];
if (isset($obdrzene)) array_push ($items, $obdrzene);
echo "<script>console.log(" + print_r($items) + ")</script>"
I když nicméně přenesu z téže stránky (001.php) do téhož skriptu (na stránce 002.php) víc údajů, pokaždé mám v konzoli jen pole s jednou položkou (jen pokaždé jinou). Z toho to vypadá, že pokaždé, když je skript v 002.php kontaktován, vytvoří pole $items znovu, místo aby připojil další položku k existujícímu poli. Čím to je?
Keeehi
Profil
Každé volání AJAXu je samostatný požadavek. Mezi jednotlivými volání se data zapomenou. Píšeme ti to tu stále dokola, tak už na to začni myslet.
Pokud by jsi na uložení dat zvolil session (což může a nemusí být správná varianta) mohl by kód vypadat takto:
if (isset($_POST['predmet'])) {
    if (!isset ($_SESSION['items'])) {
        $_SESSION['items'] = [];
    }
    array_push ($_SESSION['items'], $_POST['predmet']);
    
    echo json_encode($_SESSION['items']);
}

To uložení do pole by se dalo zapsat kratším zápisem ale pro jednoduchost jsem použil tvůj zápis.

Pro vypsání hodnot jsem zvolil správný postup. To co ten skript vypíše se bere jako obyčejný text. Proto jakýkoli jevascript je ve výstupu zbytečný, jelikož se nebude interpretovat.
Je zvykem přenášet data mezi PHP a JS ve formátu JSON. Vypsání dat do konzole by tedy pak mělo vypadat takto:
ajax.onreadystatechange = function () {
  if (ajax.readyState === 4 && ajax.status === 200) {
    console.log(JSON.parse(ajax.responseText))
  }
}

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

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

0