Přehled klient-server
Nyní, když znáte účel a potenciální výhody programování na straně serveru, podrobně prozkoumáme, co se stane, když server obdrží od prohlížeče „dynamický požadavek“. Protože většina kódu na straně serveru webové stránky zpracovává požadavky a odpovědi podobným způsobem, pomůže vám to pochopit, co musíte udělat při psaní většiny vlastního kódu.
Prerekvizity: Základní počítačová gramotnost. Základní pochopení toho, co je webový server. Cíl: Porozumět interakci klient-server na dynamickém webu a zejména tomu, jaké operace je třeba provádět pomocí kódu na straně serveru.V diskuzi není žádný skutečný kód, protože jsme ještě nevybrali webový rámec, který použijeme k napsání našeho kódu! Tato diskuse je však stále velmi relevantní, protože popsané chování musí být implementováno vaším kódem na straně serveru, bez ohledu na to, který programovací jazyk nebo webový rámec zvolíte.
Webové prohlížeče komunikují s webovými servery pomocí protokolu HTTP (HyperText Transfer Protocol). Když kliknete na odkaz na webové stránce, odešlete formulář nebo spustíte vyhledávání, prohlížeč odešle na server požadavek HTTP.
Tento požadavek zahrnuje:
Adresa URL identifikující cílový server a zdroj (např. soubor HTML, konkrétní datový bod na serveru nebo nástroj ke spuštění). Metoda, která definuje požadovanou akci (například získání souboru nebo uložení či aktualizaci některých dat). Různé metody/slovesa a jejich přidružené akce jsou uvedeny níže: GET: Získání konkrétního zdroje (např. soubor HTML obsahující informace o produktu nebo seznam produktů). POST: Vytvořte nový zdroj (např. přidejte nový článek do wiki, přidejte nový kontakt do databáze). HEAD: Získejte informace o metadatech o konkrétním zdroji, aniž byste získali tělo jako GET. Můžete například použít požadavek HEAD ke zjištění, kdy byl zdroj naposledy aktualizován, a poté použít pouze ("dražší") požadavek GET ke stažení zdroje, pokud se změnil. PUT: Aktualizujte existující zdroj (nebo vytvořte nový, pokud neexistuje). DELETE: Odstraní zadaný prostředek. TRACE, OPTIONS, CONNECT, PATCH: Tato slovesa jsou pro méně běžné/pokročilé úkoly, takže se jimi zde nebudeme zabývat. Do požadavku lze zakódovat další informace (například data formuláře HTML). Informace lze zakódovat jako: Parametry adresy URL: požadavky GET zakódují data v adrese URL odeslané na server přidáním párů název/hodnota na její konec — například http://mysite.com?name=Fred&age=11. Vždy máte otazník (?), který odděluje zbytek adresy URL od parametrů adresy URL, znak rovná se (=) oddělující každý název od jeho přidružené hodnoty a ampersand (&) oddělující každý pár. Parametry URL jsou ze své podstaty „nezabezpečené“, protože je mohou uživatelé změnit a poté znovu odeslat. V důsledku toho se parametry URL / požadavky GET nepoužívají pro požadavky, které aktualizují data na serveru. POST data. Požadavky POST přidávají nové zdroje, jejichž data jsou zakódována v těle požadavku. Cookies na straně klienta. Soubory cookie obsahují data relace o klientovi, včetně klíčů, které může server použít k určení stavu jeho přihlášení a oprávnění/přístupů ke zdrojům.Webové servery čekají na zprávy s požadavky klienta, zpracují je, když dorazí, a odpoví webovému prohlížeči zprávou HTTP Response. Odpověď obsahuje stavový kód odpovědi HTTP označující, zda byl požadavek úspěšný či nikoli (např. „200 OK“ pro úspěch, „404 nenalezeno“, pokud zdroj nelze nalézt, „403 zakázáno“, pokud uživatel nemá oprávnění k zobrazení zdroj atd.). Tělo úspěšné odpovědi na požadavek GET by obsahovalo požadovaný zdroj.
Když je vrácena stránka HTML, je vykreslena webovým prohlížečem. V rámci zpracování může prohlížeč objevit odkazy na další zdroje (např. stránka HTML obvykle odkazuje na stránky JavaScript a CSS) a odešle samostatné požadavky HTTP ke stažení těchto souborů.
Statické i dynamické webové stránky (o kterých bude řeč v následujících částech) používají přesně stejný komunikační protokol/vzory.
Můžete zadat jednoduchý požadavek GET kliknutím na odkaz nebo vyhledáváním na webu (např. na domovské stránce vyhledávače). Například požadavek HTTP, který se odešle, když na MDN vyhledáte výraz „přehled klientského serveru“, bude vypadat velmi podobně jako text zobrazený níže (nebude identický, protože části zprávy závisí na vašem prohlížeči/nastavení ).
Formát zpráv HTTP je definován ve „webovém standardu“ (RFC7230). Nemusíte znát tuto úroveň detailů, ale teď alespoň víte, kde se to všechno vzalo!
PožadavekKaždý řádek požadavku obsahuje informace o něm. První část se nazývá hlavička a obsahuje užitečné informace o požadavku, stejně jako hlavička HTML obsahuje užitečné informace o dokumentu HTML (nikoli však samotný obsah, který je v těle):
ZÍSKEJTE /cs-US/search?q=client+server+overview&topic=apps&topic=html&topic=css&topic=js&topic=api&topic=webdev HTTP/1.1 developer.mozilla.org keep-alive no-cache no-cache 1 Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, jako Gecko) Chrome/52.0.2743.116 Safari/537.36 text/html,application/xhtml+xml,application/xml;q= 0.9,image/webp,*/*;q=0.8 https://developer.mozilla.org/en-US/ gzip, deflate, sdch, br ISO-8859-1,UTF-8;q=0.7,*; q=0,7 en-US,en;q=0,8,es;q=0,6 sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; csrftoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT; dwf_section_edit=Nepravda; dwf_sg_task_completion=Nepravda; _gat=1; _ga=GA1.2.1688886003.1471911953; ffo=truePrvní a druhý řádek obsahují většinu informací, o kterých jsme hovořili výše:
Typ požadavku (GET). Adresa URL cílového zdroje (/en-US/search). Parametry adresy URL (q=client%2Bserver%2Boverview&topic=apps&topic=html&topic=css&topic=js&topic=api&topic=webdev). Cílová/hostitelská webová stránka (developer.mozilla.org). Na konci prvního řádku je také krátký řetězec identifikující konkrétní verzi protokolu (HTTP/1.1).Poslední řádek obsahuje informace o souborech cookie na straně klienta – v tomto případě soubor cookie obsahuje id pro správu relace (Cookie: sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; ...).
Zbývající řádky obsahují informace o použitém prohlížeči a druhu odpovědí, které dokáže zpracovat. Například zde můžete vidět, že:
Můj prohlížeč (User-Agent) je Mozilla Firefox (Mozilla/5.0). Může přijímat komprimované informace gzip (Accept-Encoding: gzip). Může přijmout zadanou sadu znaků (Accept-Charset: ISO-8859-1,UTF-8;q=0,7,*;q=0,7) a jazyky (Accept-Language: de,en;q=0,7,en- us;q=0,3). Řádek Referer označuje adresu webové stránky, která obsahovala odkaz na tento zdroj (tj. původ požadavku, https://developer.mozilla.org/en-US/).Požadavky HTTP mohou mít také tělo, ale v tomto případě je prázdné.
OdpověďNíže je uvedena první část odpovědi na tento požadavek. Záhlaví obsahuje následující informace:
První řádek obsahuje kód odpovědi 200 OK, který nám říká, že požadavek byl úspěšný. Vidíme, že odpověď je ve formátu text/html (Content-Type). Můžeme také vidět, že používá znakovou sadu UTF-8 (Content-Type: text/html; charset=utf-8). Hlava nám také říká, jak je velká (Content-Length: 41823).Na konci zprávy vidíme obsah těla — který obsahuje skutečný HTML vrácený požadavkem.
HTTP/1.1 200 OK Apache developer1.webapp.scl3.mozilla.com Accept,Cookie, Accept-Encoding text/html; charset=utf-8 Wed, 07 Sep 2016 00:11:31 GMT timeout=5, max=999 Keep-Alive DENY GET caching 41823...Zbytek hlavičky odpovědi obsahuje informace o odpovědi (např. byla vygenerována), server a jak očekává, že prohlížeč se stránkou naloží (např. řádek X-Frame-Options: DENY říká prohlížeči, aby nepovolil vložení této stránky na jiný web).
Při odeslání formuláře obsahujícího informace, které mají být uloženy na server, se provede HTTP POST.
PožadavekNíže uvedený text zobrazuje požadavek HTTP provedený, když uživatel odešle nové podrobnosti profilu na tomto webu. Formát požadavku je téměř stejný jako v předchozím příkladu požadavku GET, ačkoli první řádek identifikuje tento požadavek jako POST.
POST /en-US/profiles/hamishwillee/edit HTTP/1.1 developer.mozilla.org keep-alive 432 no-cache no-cache https://developer.mozilla.org 1 Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit /537.36 (KHTML, jako Gecko) Chrome/52.0.2743.116 Safari/537.36 application/x-www-form-urlencoded text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/* ;q=0.8 https://developer.mozilla.org/en-US/profiles/hamishwillee/edit gzip, deflate, br en-US,en;q=0.8,es;q=0.6 sessionid=6ynxs23n521lu21b1t136rhbv7ezngie; _gat=1; csrftoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT; dwf_section_edit=Nepravda; dwf_sg_task_completion=Nepravda; _ga=GA1.2.1688886003.1471911953; ffo=truecsrfmiddlewaretoken=zIPUJsAZv6pcgCBJSCj1zU6pQZbfMUAT&user-username=hamishwillee&user-fullname=Hamish+Willee&user-title=&user-organization=&user-zone&locale=Australia-USer-location=user-user-location=user Australia%2FMelbourne&user-irc_nickname=&user-interests=&user-expertise=&user-twitter_url=&user-stackoverflow_url=&user-linkedin_url=&user-mozillians_url-&book;Hlavní rozdíl je v tom, že adresa URL nemá žádné parametry. Jak vidíte, informace z formuláře jsou zakódovány v těle požadavku (například nové uživatelské jméno je nastaveno pomocí: &user-fullname=Hamish+Willee).
OdpověďOdpověď na požadavek je uvedena níže. Stavový kód „302 Found“ sděluje prohlížeči, že příspěvek byl úspěšný, a že musí vydat druhý požadavek HTTP, aby se načetla stránka uvedená v poli Umístění. Informace jsou jinak podobné informacím pro odpověď na požadavek GET.
HTTP/1.1 Nalezeno 302 Apache developer3.webapp.scl3.mozilla.com Cookie Accept-Encoding text/html; charset=utf-8 St, 07 Sep 2016 00:38:13 GMT https://developer.mozilla.org/en-US/profiles/hamishwillee timeout=5, max=1000 Keep-Alive DENY nelze uložit do mezipaměti; požadavek nebyl GET nebo HEAD 0Poznámka: HTTP odpovědi a požadavky zobrazené v těchto příkladech byly zachyceny pomocí aplikace Fiddler, ale podobné informace můžete získat pomocí webových snifferů (např. Websniffer) nebo analyzátorů paketů, jako je Wireshark. Můžete to zkusit sami. Použijte kterýkoli z propojených nástrojů a poté procházejte webem a upravujte informace o profilu, abyste viděli různé požadavky a odpovědi. Většina moderních prohlížečů má také nástroje, které monitorují síťové požadavky (například nástroj Network Monitor ve Firefoxu).
Statický web je web, který vrací stejný pevně zakódovaný obsah ze serveru, kdykoli je požadován určitý zdroj. Pokud tedy máte například stránku o produktu na adrese /static/myproduct1.html, bude tato stránka vrácena všem uživatelům. Pokud na svůj web přidáte další podobný produkt, budete muset přidat další stránku (např. mujprodukt2.html) a tak dále. To může začít být opravdu neefektivní – co se stane, když se dostanete na tisíce stránek produktů? Opakovali byste mnoho kódu na každé stránce (základní šablona stránky, struktura atd.), a pokud byste chtěli něco změnit na struktuře stránky – například přidat novou sekci „související produkty“, pak byste musí změnit každou stránku zvlášť.
Poznámka: Statické weby jsou skvělé, když máte malý počet stránek a chcete všem uživatelům poslat stejný obsah. Jejich údržba však může mít značné náklady, protože se počet stránek zvětšuje.
Pojďme si shrnout, jak to funguje, tím, že se znovu podíváme na diagram statické architektury webu, na který jsme se podívali v minulém článku.
Když chce uživatel přejít na stránku, prohlížeč odešle požadavek HTTP GET s uvedením adresy URL jeho stránky HTML. Server načte požadovaný dokument ze svého systému souborů a vrátí odpověď HTTP obsahující dokument a stavový kód odpovědi HTTP "200 OK" (označující úspěch). Server může vrátit jiný stavový kód, například „404 nenalezeno“, pokud soubor není na serveru přítomen, nebo „301 přesunuto trvale“, pokud soubor existuje, ale byl přesměrován do jiného umístění.
Server pro statický web bude muset vždy zpracovávat pouze požadavky GET, protože server neukládá žádná upravitelná data. Nemění ani své odpovědi založené na datech požadavku HTTP (např. parametry adresy URL nebo soubory cookie).
Porozumění tomu, jak fungují statické stránky, je nicméně užitečné při učení programování na straně serveru, protože dynamické stránky zpracovávají požadavky na statické soubory (CSS, JavaScript, statické obrázky atd.) úplně stejným způsobem.
Dynamické stránky jsou takové, které mohou generovat a vracet obsah na základě konkrétní adresy URL požadavku a dat (spíše než vždy vracet stejný pevně zakódovaný soubor pro konkrétní adresu URL). Na příkladu stránky produktu by server uložil „data“ produktu do databáze spíše než jednotlivé soubory HTML. Při přijetí požadavku HTTP GET pro produkt server určí ID produktu, načte data z databáze a poté vytvoří stránku HTML pro odpověď vložením dat do šablony HTML. To má oproti statickému webu hlavní výhody:
Použití databáze umožňuje efektivní ukládání informací o produktu, a to způsobem, který lze snadno rozšířit, upravit a vyhledávat.
Použití šablon HTML velmi usnadňuje změnu struktury HTML, protože to je třeba provést pouze na jednom místě, v jedné šabloně, a ne na potenciálně tisících statických stránek.
Tato část poskytuje podrobný přehled „dynamického“ cyklu požadavků a odpovědí HTTP, který vychází z toho, na co jsme se podívali v minulém článku a mnohem podrobněji. Abychom „udrželi věci reálné“, použijeme kontext webové stránky manažera sportovních týmů, kde si trenér může vybrat název týmu a velikost týmu ve formě HTML a získat zpět navrhovanou „nejlepší sestavu“ pro svůj příští zápas.
Na obrázku níže jsou zobrazeny hlavní prvky webové stránky „trenér týmu“ spolu s číslovanými štítky pro sekvenci operací, když trenér vstoupí do seznamu „nejlepšího týmu“. Části webu, díky kterým je dynamický, jsou webová aplikace (takto budeme odkazovat na kód na straně serveru, který zpracovává HTTP požadavky a vrací HTTP odpovědi), databáze, která obsahuje informace o hráčích, týmech, trenérech a jejich vztahy a šablony HTML.
Poté, co trenér odešle formulář s názvem týmu a počtem hráčů, následuje sled operací:
Webový prohlížeč vytvoří požadavek HTTP GET na server pomocí základní adresy URL pro zdroj (/best) a zakóduje tým a číslo hráče buď jako parametry URL (např. /best?team=my_team_name&show=11) nebo jako součást vzor adresy URL (např. /nejlepší/název_mého_týmu/11/). Požadavek GET se používá, protože požadavek pouze načítá data (neupravuje data). Webový server zjistí, že požadavek je „dynamický“ a předá jej webové aplikaci ke zpracování (webový server určí, jak zacházet s různými URL na základě pravidel pro porovnávání vzorů definovaných v jeho konfiguraci). Webová aplikace identifikuje, že záměrem požadavku je získat „seznam nejlepších týmů“ na základě URL (/best/) a z URL zjistí požadovaný název týmu a počet hráčů. Webová aplikace pak získá požadované informace z databáze (pomocí dalších „interních“ parametrů k definování, kteří hráči jsou „nejlepší“, a případně také získání identity přihlášeného trenéra z cookie na straně klienta). Webová aplikace dynamicky vytváří stránku HTML vložením dat (z databáze) do zástupných symbolů v šabloně HTML. Webová aplikace vrátí vygenerovaný HTML do webového prohlížeče (prostřednictvím webového serveru) spolu se stavovým kódem HTTP 200 ("úspěch"). Pokud cokoli brání vrácení kódu HTML, webová aplikace vrátí jiný kód – například „404“, což znamená, že tým neexistuje. Webový prohlížeč poté začne zpracovávat vrácený HTML a odesílá samostatné požadavky na získání jakýchkoli dalších souborů CSS nebo JavaScript, na které odkazuje (viz krok 7). Webový server načte statické soubory ze systému souborů a vrátí je přímo do prohlížeče (opět platí, že správné zacházení se soubory je založeno na konfiguračních pravidlech a shodě vzorů URL).Operace aktualizace záznamu v databázi by byla zpracována podobně , kromě toho, že jako každá aktualizace databáze by měl být požadavek HTTP z prohlížeče zakódován jako požadavek POST.
Úkolem webové aplikace je přijímat požadavky HTTP a vracet odpovědi HTTP. Zatímco interakce s databází za účelem získání nebo aktualizace informací jsou velmi běžné úkoly, kód může dělat jiné věci současně nebo s databází vůbec neinteragovat.
Dobrým příkladem dalšího úkolu, který může webová aplikace provést, je odeslání e-mailu uživatelům s potvrzením jejich registrace na webu. Web může také provádět protokolování nebo jiné operace.
Kód webu na straně serveru nemusí v odpovědi vracet úryvky/soubory HTML. Místo toho může dynamicky vytvářet a vracet jiné typy souborů (text, PDF, CSV atd.) nebo dokonce data (JSON, XML atd.).
Myšlenka vracet data do webového prohlížeče, aby mohl dynamicky aktualizovat svůj vlastní obsah (AJAX), existuje již nějakou dobu. V poslední době se staly populárními „jednostránkové aplikace“, kde je celý web napsán pomocí jediného souboru HTML, který se v případě potřeby dynamicky aktualizuje. Webové stránky vytvořené pomocí tohoto stylu aplikací přenášejí ze serveru na webový prohlížeč velké výpočetní náklady a mohou vést k webovým stránkám, které vypadají, že se chovají mnohem více jako nativní aplikace (vysoce reagující atd.).
Webové rámce na straně serveru značně usnadňují psaní kódu pro operace popsané výše.
Jednou z nejdůležitějších operací, které provádějí, je poskytování jednoduchých mechanismů pro mapování adres URL pro různé zdroje/stránky na konkrétní funkce obsluhy. To usnadňuje udržování kódu spojeného s každým typem zdroje odděleně. Má také výhody, pokud jde o údržbu, protože můžete změnit adresu URL používanou k poskytování konkrétní funkce na jednom místě, aniž byste museli měnit funkci obslužného programu.
Zvažte například následující kód Django (Python), který mapuje dva vzory adres URL na dvě funkce zobrazení. První vzor zajišťuje, že požadavek HTTP s adresou URL zdroje /best bude předán funkci s názvem index() v modulu pohledů. Požadavek, který má vzor "/best/junior", bude místo toho předán funkci zobrazení junior().
z django.conf.urls importovat urlfrom . import viewsurlpatterns = [url(r'^$', views.index),url(r'^junior/$', views.junior),]Poznámka: První parametry ve funkcích url() mohou vypadat jako trochu liché (např. r'^junior/$'), protože používají techniku porovnávání vzorů nazývanou „regulární výrazy“ (RegEx nebo RE). V tuto chvíli nepotřebujete vědět, jak regulární výrazy fungují, kromě toho, že nám umožňují porovnávat vzory v adrese URL (spíše než pevně zakódované hodnoty výše) a používat je jako parametry v našich funkcích zobrazení. Jako příklad může skutečně jednoduchý RegEx říkat „shodujte s jedním velkým písmenem, po kterém následuje 4 až 7 malých písmen“.
Webový rámec také usnadňuje funkci zobrazení načítání informací z databáze. Struktura našich dat je definována v modelech, což jsou třídy Pythonu, které definují pole, která mají být uložena v podkladové databázi. Pokud máme model pojmenovaný Team s polem „team_type“, můžeme použít jednoduchou syntaxi dotazu a získat zpět všechny týmy, které mají konkrétní typ.
V příkladu níže je uveden seznam všech týmů, které mají přesný (rozlišují se malá a velká písmena) team_type „junior“ – všimněte si formátu: název pole (team_type) následovaný dvojitým podtržením a poté typ zápasu, který se má použít (v přesně tento případ). Existuje mnoho dalších typů zápalek a můžeme je řetězit. Můžeme také kontrolovat pořadí a počet vrácených výsledků.
from django.shortcuts import renderfrom .models import Teamdef junior(request):list_teams = Team.objects.filter(team_type__exact="junior")context = {'list': list_teams}return render(request, 'nejlepší/index.html' , context)Poté, co funkce junior() získá seznam juniorských týmů, zavolá funkci render() a předá původní HttpRequest, HTML šablonu a objekt "context" definující informace, které mají být zahrnuty do šablona. Funkce Therender() je užitečná funkce, která generuje HTML pomocí kontextu a šablony HTML a vrací jej v objektu HttpResponse.
Webové rámce vám samozřejmě mohou pomoci se spoustou dalších úkolů. V dalším článku diskutujeme o mnoha dalších výhodách a některých oblíbených možnostech webového rámce.
V tuto chvíli byste měli mít dobrý přehled o operacích, které musí kód na straně serveru provádět, a znát některé způsoby, jak to může webový rámec na straně serveru usnadnit.
V následujícím modulu vám pomůžeme vybrat nejlepší webový rámec pro váš první web.
PREV: Jak vytvořit virtuálního hostitele Nginx (AKA Server Blocks ...
NEXT: Automatická aktivace virtuálního počítače v systému Windows Server...