HTTP metody GET a POST

Školení, která pořádám

Jistě nemusím vysvětlovat, jaký je rozdíl mezi HTTP metodami GET a POST. Při použití metody GET se veškerá formulářová data předají jako součást URL za otazníkem, při použití metody POST se předají v těle dotazu, takže v URL nejsou vidět. Z toho plyne i vhodnost jejich použití – pokud se předaná data dají chápat jako parametry stránky (tedy např. předání ID článku nebo vyhledávaného řetězce), je vhodné je poslat metodou GET, v ostatních případech je lepší použít metodu POST (obzvláště pokud je dat hodně – např. Internet Explorer dokáže zpracovat URL jen do délky 2083 znaků). Použití této metody by také mělo být samozřejmé v případě, kdy předaná data obsahují citlivé údaje (jako např. heslo), protože jinak se tato data dají získat řadou způsobů (např. z historie prohlížeče, na proxy serveru, z logů webového serveru nebo z HTTP hlavičky Referer).

Při pokusu o obnovení stránky získané metodou POST se prohlížeče obvykle zeptají, jestli uživatel chce data poslat znovu. Pokud se tomu chceme vyhnout a pokud navíc chceme zamezit např. opětovnému vložení diskusního příspěvku, dá se to jako obvykle řešit několika způsoby, z nichž nejčistší je poslání HTTP hlavičky Location spolu s odpovídajícím stavovým kódem.

<?php
mysql_query("INSERT INTO tabulka (data) VALUES ('" . mysql_real_escape_string($_POST["data"]) . "')"); // zpracování dat
header("Location: vysledek.php", true, 303); // přesměrování na stránku s výsledkem
?>

Funkce header při poslání hlavičky Location stavový kód automaticky nastavuje na 302, který by měl zachovat použití metody POST i pro odkazovaný dokument (což nechceme). Např. Internet Explorer 6.0 sice metodu změní na GET, ale např. Firefox 1.0 ji opravdu ponechá, takže místo toho raději explicitně nastavíme stavový kód na 303.

Dlužno podotknout, že hlavička Location by se podle normy vždy měla posílat s absolutním URL. Všechny mě známé prohlížeče se sice spokojí i s relativním URL, ale norma je norma…

<?php
$cesta = substr($_SERVER["PHP_SELF"], 0, strrpos($_SERVER["PHP_SELF"], "/"));
header("Location: http://$_SERVER[SERVER_NAME]$cesta/vysledek.php", true, 303);
?>

Pokud používáte sessions spolu s jejich transparentním předáváním, je vhodné na konec URL přidat "?" . SID. V konstantě SID je uložen řetězec potřebný pro předání session identifikátoru, v případě existence session cookie je prázdný.

Jakub Vrána, Seznámení s oblastí, 13.5.2005, diskuse: 74 (nové: 0)

Diskuse

ikona dgx:

doplnil bych jedno zamyšlení, kdy použít GET a kdy POST - http://www.dgx.cz/trine/item/jak-na-formulare-post-a-get

Jan Tichý:

$_POST[data] -- buď Ti tam někde chybí definice tý konstanty data, anebo velký fuj. Pro všechny ostatní -- tímhle se určitě neřiďte, správně je samozřejmě jen a pouze $_POST['data'] protože data není žádná konstanta, alébrž řetězec.

ikona Jakub Vrána OpenID:

To je pořád dokola. <?php "$_POST[data]"; ?> je naprosto v pořádku, 'data' se v tomto kontextu chápe jako řetězcový klíč. Jako konstanta se to chápe v kontextu <?php $_POST[data] ?>, což nikde nepoužívám. <?php "$_POST['data']"; ?> samozřejmě nefunguje vůbec. Kdo nevěří, ať si to vyzkouší nebo se podívá do dokumentace: http://www.php.net/manual/en/language.types.string.php

Jan Tichý:

No vidiš to, další nesystémový nesmysl v PHP, o kterém jsem dokonce ani nevěděl. Díky za upozornění. 

Nicméně já osobně bych se tomuhle bastlu doporučoval všemožně vyhýbat, protože je to opravdu na hlavu postavená nesystémová kravina (ostatně, komentář u dané ukázky v dokumentaci je také docela výmluvný).

A mně je to vlastně jedno, jednoduché uvozovky rulez :).

salko:

podla spravnosti by malo byt:
<?php "{$_POST['data']}"; ?>

ked pouzijete:
<?php "$_POST[data]"; ?>
moze sa stat, ze keby ste mali vytvorenu konstantu data, tak by sa pouzil jej obsah.

ikona Jakub Vrána OpenID:

Ale vůbec ne. Budu trpělivý a napíšu to ještě jednou - buď se podívej do dokumentace nebo si to vyzkoušej:
<?php
$ar
= array("data" => "OK", "baba" => "fuj");
define("data", "baba");
echo
"$ar[data]\n"; // OK
echo $ar[data]; // fuj
?>

Zápis se složenými závorkami je také správně, ale delší.

salko:

no to je zaujimave, nikdy som to neskusal. Ale v kazdom pripade ja pre vsetky premenne v dvojitych uvodzovkach pouzivam kontrukciu "{}", pre mna je to prehladnejsie a pre parser jednoduchsie. Kedysi som si robil rychlistny test a vysledky boli lepsie pre "{$variable}" ako "$variable". Bolo to este pre php 4.3.0.

salko:

Inak sorry, pisal som z horucou hlavou, necital som vsetky prispevky spatne, takze som preletel vase vysvetlenie.
Ale aj tak vdaka za vysvetlenie ohladom 302/303, doteraz som asi chodil iba na 302.

Petr Fišera:

ahehe :D se divim že už jste se nenasr** :D

Qwerty:

takhle je to správně

<?php "".$_POST['data'].""; ?>

Miloš Brecher:

Dávám přednost zápisu <?php  $_POST['data'];  ?>.

endlife:

na toto téma jsem nedávno docela dobře zakysl - jak sestavím header posílající postdata? asi to bude primitivní, ale nikde jsem to nenašel.

nemám žádné podezřelé důvody, situace je asi taková - chci propojit hostingový mail s frontendem webu. což není problém, udělám formulář a nasměruju jej na správný cíl. jenže, čistě pro komfort, bch byl rád, kdyby uživatel nemusel mít v inputu předávájící adresu value="@server.xy", ale aby tento text byl až za inputem a v políčku nic nezavazelo.

takže potřebuju přijmout postdata, připojit ke jménu '@server.xy' a poslat dál metodou post..

díky za nějakou radu nebo aspoň popření správnosti této myšlenky :-)

ikona Jakub Vrána OpenID:

Hlavičku posílající postdata sestavit nejde. Pokud se má k datům něco připojit, musíš se spokojit s řešením u klienta v JavaScriptu. Jiná možnost je odeslat data PHP skriptem a přeposlat je klientovi (jak na to jsem psal dříve - http://php.vrana.cz/eurotel-sms.php), to ale obvykle není to, co chceme.

p:

samozrejme, ze to jde.. muzes pouzit WHOAHTTPStream z baliku whoa.stream.http.php stahnutelne na http://www.whoa-framework.org.

ikona Jakub Vrána OpenID:

Skript samozřejmě může stáhnout data metodou POST, ani není potřeba žádný framework a vystačíš si se standardními funkcemi PHP. Ale neexistuje hlavička, kterou bych klientovi řekl - podívej se na dané URL a pošli mu tato data metodou POST.

p:

ja myslim jakube, ze se ptal prave na to :) ale nejak se ztracim v tve myslence "podivej se na URL a posli data POSTem", bavime se presne o cem? :) ohledne frameworku - samozrejme se na to nespousti, jen jsem to poslal jako ukazku konkretni implementace.

ikona Jakub Vrána OpenID:

Stavový kód 303 říká klientovi, že se má podívat na URL poslané v hlavičce Location. Obdoba tohoto principu pro metodu POST neexistuje.

ikona dgx:

> Ale neexistuje hlavička, kterou bych klientovi řekl - podívej se na dané URL a pošli mu tato data metodou POST.

Jen pro doplnění, je možné provést přesměrování metodou POST (kód 307), ale přenesou se data sestavená v přechozí stránce, tedy není možné je modifikovat.

ikona Jakub Vrána OpenID:

A ještě chování v jednotlivých prohlížečích: IE 6 bez keců přesměruje a předá data, Firefox 1.5 a Opera 9 se v souladu s normou nejprve zeptá.

ikona dgx:

Tak, a teď ať se přihlásí ten, koho to překvapuje :-))

imploder:

Mám podobný problém. Ve formuláři mám 2 velká pole <textarea>, takže se celý formulář musí odesílat metodou POST. Když některé z polí formuláře uživatel nevyplní, skript, který data z formuláře zpracovává pomocí funkce header přesměruje prohlížeč zpět na stránku s formulářem, kde se zobrazí upozornění, že je potřeba pole vyplnit. Problém je v tom, jak docílit toho, aby skript zpracovávající formulář poslal zpět do formuláře všechna všechna data (jinak by uživatel po upozornění na nevyplněné pole nemusel vyplňovat všechno znovu), když formulář obsahuje také 2 zmíněná pole <textarea>, která můžou obsahovat mnoho textu a musí se proto posílat metodou POST.

ikona Jakub Vrána OpenID:

Nejlepší je skript nechat zpracovat souborem, který zobrazuje formulář, a pouze když to dobře dopadne, tak přesměrovat na informaci o výsledku.

pet:

popripade si precti neco o SESSION. je to jeden ze spusobu jak k takovemu efektu dojit.

Jan Tichý:

Jinak jsem ale chtěl poděkovat za ten postřeh o HTTP 303, dodneška jsem pro daný účel používal právě odpověď 302...

ikona spaze:

tak tak, musim se pridat. Dalsi dik patri za upozorneni na dalsi parametry (replace, http_response_code) u header().

K relatvni hlavicce, lynx zahlasi nejakej warning, ze je relativni cesta, ale pak pokracuje vesele dal.

K presmerovani pouzivam PEAR::HTTP::redirect(), ale problem o kterym jsem az do ted nevedel, ze neumoznuje custom status code.

A jeste jedna vec, kdysi jsem napsal funkci realURL(), ktera pracuje podobne jako realpath(), s tim, ze soubor nemusi existovat, samozrejme ;)

Pavel Z.:

Taky díky za ty parametry! Všichni, kteří použivájí českou dokumentaci je neznají, protože je tam nějak zapomněli uvést. Pokoušel jsem se najít někde mail na českého "dokumentaristu", ale bohužel jsem nic nenašel.

Odteď používám už jen anglickou verzi. ;-)

ikona Jakub Vrána OpenID:

Česká dokumentace je žalostně zastaralá. Chvíli jsem se o ni zkoušel starat i já, ale je to nad mé síly, raději pracuji na anglickém originálu.

Mail na skupinu české dokumentace je doc-cs@lists.php.net, takhle zásadní chyby budou nejspíš opraveny (tuhle už jsem v CVS opravil, na webu se objeví při příštím buildu). Pokud chcete pomoci, tak se na ten mail taky ozvěte.

Andrew:

Chtěl jsem se zeptat k následující větě z dokumentace: "Many pre-HTTP/1.1 user agents do not understand the 303 status."
Které že "user agents" to jsou? Má smysl se jimi zabývat? Omluvte moji lenost, že nezjišťuji, od které verze jaký prohlížeč podporuje HTTP 1.0, ale zajímá mě, jestli tady už někdo narzail.

ikona Jakub Vrána OpenID:

Řekl bych, že prohlížeče s tím problém nemají už dávno, ale problém by mohly mít některé proxy (tam situaci podrobně neznám) a vyhledávače. Např. MSNbot HTTP/1.0 používá a jestli si poradí s 303 nevím.

Andrew:

Měl bych dotaz. Přijde mi, že tohle

$cesta = substr($_SERVER["PHP_SELF"], 0, strrpos($_SERVER["PHP_SELF"], "/"));

vrátí vždycky prázdný řetězec, neboť $PHP_SELF začíná s "/". Nebo tomu tak vždycky není?

ikona Jakub Vrána OpenID:

Úvaha je správná, ale použita je funkce strrpos (poslední výskyt) a ne strpos.

Andrew:

Omlouvám se, už mi z toho monitoru oči špatně vidí. To je pak jasné. Ještě jednou promiň za plnění blogu a mrhání Tvym časem hloupostmi. (Teda kdo vymýšlel názvy těch funkcí ;-))

Saman:

Jj, taky uz jsem na tyhle dve funkce narazil, v diplomce, dve hodiny jsem se snazil ladit a prijit na to co nefacha, paxem zjistil ze jedno pismenko mi chybi.. :|

petr:

prosim pozor - v tomto miste je to nebezpecne!
mysql_query("INSERT INTO tabulka (data) VALUES ('$_POST[data]')"); // zpracování dat

do mysql dotazu nikdy nevkladejte neosetreny vstup od uzivatele ($_POST[data]). Jednak lze snadno 'shodit' sql dotaz (staci mit na konci $_POST[data] zadane obracene lomitko, druhak je to dale zneuzitelne hackery.  Vice se da zjistit napr. na google zadanim 'sql script injection'

petr:

Omlouvam se, Jakube, nasel jsem Vas clanek kde presne o tomto pisete. Vy to znate, ale nebylo by dobre na to upozornovat ctenare pod clankem? Podle diskuze vidim spoustu prispevku od lidi kteri s PHP zacinaji a pro ne by to mohlo zpusobit casem skarede zklamani (ze se to naucili od serveru kteremu  duveruji) a opravy desitek skriptu...

ikona Jakub Vrána OpenID:

Už jsem to rozebíral několikrát. Ukázky počítají se zapnutým magic_quotes_gpc (a třeba taky vypnutými E_NOTICE), uvádět to vždy znovu pod každou ukázkou mi přijde nadbytečné, obzvlášť s přihlédnutím k tomu, že na většině webhostingů je to zapnuté.

ikona Jakub Vrána OpenID:

Kód jsem předělal na magic_quotes_gpc = Off a zmínil jsem to v patičce.

ikona Jakub Vrána OpenID:

Požadované nastavení jsem umístil do patičky webu.

lukas:

hezkdy den,
chtel jsem se zeptat co je to za parametr true v header?
Respektive po presmerovani mam pristup kde k tomu zda je true?

ikona Jakub Vrána OpenID:

http://www.php.net/manual/en/function.header.php: "The optional replace parameter indicates whether the header should replace a previous similar header, or add a second header of the same type."

Adam Holub:

Nejdřív malá poznámka:
Pokud bude web server přístupný jen přes https, uvedený příklad selže. Doporučuju následující úpravu:
<?php
$cesta
= substr($_SERVER["PHP_SELF"], 0, strrpos($_SERVER["PHP_SELF"], "/"));
$protokol = ($_SERVER["HTTPS"] ? "https" : "http");
header("Location: $protokol://$_SERVER[SERVER_NAME]$cesta/vysledek.php", true, 303); ?>

No a už vůbec to nebude fungovat, pokud php běží na serveru a.x.cz dostupném jen přes forward (rewrite) např. b.x.cz/asrv.
Header by pak měl mít podle normy tvar
Location: http://b.x.cz/asrv/cesta/vysledek.php
V proměnné $_SERVER['SERVER_NAME'] je 'a.x.cz', objeví se proměnná $_SERVER['HTTP_X_FORWARDED_HOST']='b.x.cz' a $_SERVER['HTTP_X_FORWARDED_SERVER']='b.x.cz'. Ale o tom, že součástí cesty má být /asrv/, se ze žádné proměnné nedozvím. Obecné řešení jsem nenašel, buď to tam musím napsat natvrdo a doufat, že správce serveru ten forward nepředělá, nebo se vykašlat na normu, použít relativní odkaz a doufat, že si s tím všechny prohlížeče poradí.
Nebo někoho obecné řešení napadne?

skybedy:

Je to asi začátečnický dotaz, ale proč ve formulářích nepoužívat výhradně $_POST[data]?

ikona Jakub Vrána OpenID:

Pokud je data z formuláře možné chápat jako parametry stránky (vyhledávaný text, ID článku, číslo zobrazované stránky, ...), je lepší použít metodu GET. Důvod je ten, že při obnovení stránky se prohlížeč neptá na opětovné odeslání dat a s takovouto stránkou správně pracují i cache, vyhledávače a spol.

Metodu POST je naopak lepší použít v případě, kdy lze formulářová pole chápat jako vstupní data pro stránku - registrační údaje, druh zboží k nákupu, ...

SAX:

kurňa, chlapi! jáááá vááám tak závydím, že viete o čom hovoríte! tiež by som chcel toto všetko vedieť, ale som samouk a teda total magor do týchto vecí!!!
no čo, možno raz to pochopím!! zdar všetkým!

pce75:

Zdravím.
Kluci potřebuju tohle:
ve formu mám matici o poctu n_input/text se stejnym name (treba txt_zahlavi)a potrebuji metodou POST vratit pole hodnot. S povol. global. promennymi bych predpokladal hodnoty napr. $txt_zahlavi[1], $txt_zahlavi[2]... Ale nevim zda a jak volat pole se zakazanymi globalnimi - $_POST['txt_zahlavi[1]'] je predpokladam zhovadilost.

Pomuze nekdo? :-))
Diky Petr

ikona Jakub Vrána OpenID:

Při name="txt_zahlavi[1]" lze použít $_POST["txt_zahlavi"][1].

pce75:

Jakube diky moc. Je nutne pri generovani INPUT prvku indexovat ? Nemuzu proste jen echo "<INPUT name=\"txt_zahlavi[]\">;
a pak cist pres

foreach($_POST[txt_zahlavi] as $val =>$index)?

Díky
Petr

ikona Jakub Vrána OpenID:

To jde taky.

Bart:

dobry den,
mozna budu za lamu,ale byl bych rad, kdyby mi nekdo poradil s nasledujicim problemem. Mam XML soubor, ktery potrebuji automaticky (z cronu) POSTnout pres formular skriptu, ktery je na serveru v odlisne domene (napr.http://www.neco.cz/apps/news.aspx). Skript mi vrati do proudu plain text s odpovedi "ok" (data jsou v poradku) nebo "error" (xml je spatne). Netusite nekdo jak result toho skriptu zachytit a zapsat treba do souboru nebo poslat mailem? Automaticke odeslani formulare resim pres <body onload=formular.submit()> - mozna je to taky kravina.
Ke skriptu, ktery data prijima, nemam zadnou moznost pristupu.

Diky za jakoukoliv pomoc.

Bart

ikona Jakub Vrána OpenID:

Třeba takhle:
<?php
$context
= stream_context_create(array('http' => array('method' => 'POST', 'content' => 'field1=1&field2=2')));
readfile('http://example.com/', false, $context);
?>

JiRi:

Je mozne pomoci techto metod predavat i promennou typu array? Jak?
Dik

ikona Jakub Vrána OpenID:

Ano, je to možné pomocí konstrukce ?a[]=1&a[]=2. V PHP z toho potom vznikne pole $_GET["a"] = array(1, 2).

JiRi:

Dik. Jestli to dobre chapu, tak prebrat je muzu jako pole, ale posilat musim oddelene jednotlive slozky pole. (neni to optimalni, ale aspon neco;)

ikona Jakub Vrána OpenID:

Ano. K sestavení řetězce se dá použít funkce http_build_query().

Luky:

Ahoj,
mám jeden problém, který se mi nepodařilo vygooglit:
mám diskuzi a přidání příspěvku je dělany samostatným souborem.php, který při úspěchu končí header(Location...) - aby se to nekešovalo a aby to po stisknutí F5 nenabízelo znovu poslat data.
problém je, že při použití location nejde posílat žádné parametry. šlo by to sice poslat jako součást url (xxx?a=1&b=2), ale to nechci kvuli rewrite modu.
nedaj se nějak poslat parametry v hlavičce, třeba jako kdyby to bylo odeslané formulářem metodou post?

ikona Jakub Vrána OpenID:

Při přesměrování se žádná data metodou POST poslat nedají. Poslat je v URL je nejobvyklejší řešení, někdy může dávat smysl je uložit do session proměnné.

Luky:

ok, díky za odpověď.
jak to teda prosimtě funguje? když kliknu ve formuláři na submit, tak to vytvoří nějakou hlavičku s parametrama který jsem vyplnil do formuláře. tak jsem si myslel, že bych ji vytvořil sám a on už by nepoznal, zda se předtim kliklo na submit... nebo ne...?

ikona Jakub Vrána OpenID:

Při použití metody POST se data neposílají v hlavičce, ale v těle zprávy. Protokol HTTP nedovoluje předat tělo zprávy, pokud se použije hlavička Location.

Luky:

aha.
a ještě poslední otázka: je bezpečné ukládat citlivé informace do globálních proměnných?
(pokud ano, tak by se mi tím problém vyřešil)
díky

Verotor:

mám takový problém, pokouším se odeslat data formuláře metodou POST, když se ale v PHP skriptu snažím s těmito daty pracovat přes kolekci $_POST['...'] hlásí skript chybu, že je nedefinovaný index ... po umorném bádání jsem zjistil, že se všechna data z formuláře nachází v kolekci $_GET['..'] dokázal by mi někdo říct proč? zkoušel jsem hledat všude možně v nastaveních, ale nic...

Verotor:

K mému poslednímu příspěvku...zjistil jsem, že je vždy použita metoda GET i když je ve zdrojovém kodě html stránky použita metoda POST... Nevěděl by někdo, kde se to dá nastavit? Používám server Apache na svém notebooku, takže pracuji s localhost

radek:

Dobr7 den,
mohl by mi pros9m n2kdo poradit? Přes zařízení čidla posílám periodicky po 5 sec HTTP GET na server.Když se podívám do apache access.logu, mám tam: "GET /tme/aplikace/n.php?mod=02&name=t2&type=0&stat=0&temp=273&watch=0&max=1250&min=-550&hyst=0&id=teplota%20 HTTP/1.1" 200 125

PHP scriptem pak chci zapisovat do databaze dané hodnoty s datem. Nejak mi ale nejde načíst hodnoty do proměnné.Pokud zanedbám zápis do databáze a chci je jen zobrazit, nejde mi to. Práva na souboru jsou v poradku.

<?php

$TEMP
= $_GET["teplota"];

// Jestlize prijde jako paramet teplota, zapis ho do souboru a zobraz vysledek
// Jestlize nema soubor patricna prava, vypis chybove hlaseni

if ($TEMP)
    {
        if ($file=@fopen("teploty.dat", "w"))
        {
            $text=fwrite($file,$ok);
            fclose($file);
            echo $TEMP;
        }
        else
        {
            echo "Chyba - soubor teploty.dat nema pravo pro zapis!";
        }
}

# Jestlize neprijde teplota jako parametr, napis "bez teploty"

if (!$TEMP)
    {

            echo "bez teploty";
        }
?>

Děkuji za váš nápad či připomínku.

Radek:

Omlouvám se za čestinu v předchozím článku. Problém se mi již podařilo vyřešit.

Zacatecnik:

Zdravim,
Mohl by mi prosim někdo poradit jak získat úplnou cestu k souboru do proměnné? Použil jsem metodu GET (POST je stejný)a Input type "file". Při odeslání se ale jako proměnná odesílá pouze název souboru, nikoli celá cesta.
//Tedy:
<form action="skript.php" method="get">
<input type="file" name="soubor">
// vkládám třeba "C:\Slozka\nejakysoubor.txt"
<input type="submit" value"OK">
//V skript.php tedy:
$soubor = $_GET['soubor'];
echo $soubor;
//echo mi vypíše pouze - nejakysoubor.txt
Jak docílit aby vypsalo  - C:\Slozka\nejakysoubor.txt
Díky

ikona Jakub Vrána OpenID:

Prohlížeče to nepředávají kvůli bezpečnosti.

ikona Karel Dytrych:

A neslo by to tam doplnit do skryteho pole javascriptem pred odeslanim?

ikona Jakub Vrána OpenID:

Ne, ze stejného důvodu.

Začátečník:

Tak díky, pouštím z hlavy, najdu jiný způsob. Třeba pomůže upload, nebo tak něco.

ikona v6ak:

Je to hodně důležité? Napadá mě, že by to mohlo jít obejít a jsem si s tím skoro jist. Tak jestli to mám psát sem, nebo vyzkoušet a napsat vývojářům prohlížečů...

ikona Jakub Vrána OpenID:

Asi to klidně napiš sem.

ikona v6ak:

Tak jo. Napadlo mě následující: co takhle ten formulář posílat třeba do iframe s tím, že by se tam nejdřív poslal metodou GET, čímž se AFAIK pošle pouze název souboru (kompatibilitu nevím), a pak by se to přepnulo a poslal by se formulář metodou post atd. aby se poslal skutečný soubor.

ikona Jakub Vrána OpenID:

Právě že se pošle jen název souboru, ten se posílá i normálně a PHP ho zpřístupňuje. Začátečník chtěl celou cestu.

ikona v6ak:

Tak jsem to vyzkoušel v IE6, FF, Operě a Chrome (IE7 nemám, protože od nové instalace systému jsem se webem prakticky nezabýval - neměl jsem důvod instalovat IE7).
FF + Opera: pošlou jen název
IE6: pošle celou cestu
Chrome: soubor u GETu ignoruje
Stejně jsem to zkusil s metodou POST bez správně nastaveného způsobu posílání (pouze <form action="file-upload.php" method="post">) a výsledky byly stejné.
To je ale zajímavé - žebych se s tím tehdy setkal v IE, když asi 6 lez používám prohlížeč od Mozilly (Mozilla Suite/Mozilla Firefox)? (Samozřejmě, pokud to selže v jednom, nemají zpravidla smysl testy ve všech prohlížečích.) Spíš to dřív bylo jinak.
Nicméně, ať je to jakkoli zajímavé, na jednom se shodnem - je to pro většinu případů v praxi nepoužitelné.

ikona v6ak:

// IE8 pochopitelně taky ne...
Tak nakonec se brání ze jmenovaných testovaných pouze Firefox - u ostatních (Chrome+Opera) se mi to podařilo jinou cestou:
  var s = [];
  var field = document.forms.upload.elements.f;
  s.push('file: '+field.value);
  field.type='text';
  s.push('text: '+field.value);
  alert(s.join('\n'));
V IE6 selže přístup k type. Nepokoušel jsem se to obejít, protože tu je už jiná cesta.
Firefox se chová rozumně - u input type="file" hodnotu neprozradí a při změně typu vymaže hodnotu.
Opera sice chrání input type="file" před čtením value stejně jako Firefox (řekne jen holý název), ale změně type neodolá.
A u Chrome narozdíl od Opery není potřeba ani měnit type.
Jen můj oblíbený Firefox odolal oboum útokům :-)

Vložit komentář

Používejte diakritiku. Vstup se chápe jako čistý text, ale URL budou převedeny na odkazy a PHP kód uzavřený do <?php ?> bude zvýrazněn. Pokud máte dotaz, který nesouvisí s článkem, zkuste raději diskusi o PHP, zde se odpovědi pravděpodobně nedočkáte.

Jméno: URL:

avatar © 2005-2017 Jakub Vrána. Publikované texty můžete přetiskovat pouze se svolením autora. Ukázky kódu smíte používat s uvedením autora a URL tohoto webu bez dalších omezení Creative Commons. Můžeme si tykat. Skripty předpokládají nastavení: magic_quotes_gpc=Off, magic_quotes_runtime=Off, error_reporting=E_ALL & ~E_NOTICE a očekávají předchozí zavolání mysql_set_charset. Skripty by měly být funkční v PHP >= 4.3 a PHP >= 5.0.