LXF83:Python
Lockal (обсуждение | вклад) м (восстановление кавычек в коде AWB) |
|||
Строка 1: | Строка 1: | ||
− | {{ | + | http://www.textalmoncnad.com |
+ | {{Цикл/Python}} | ||
− | == | + | == РабоÑа Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ даннÑÑ
и web-пÑогÑаммиÑование == |
− | '' ''' | + | '' '''ЧаÑÑÑ 3''' ЧÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¼Ð¾Ñнее ÑвÑзки «база даннÑÑ
+ инÑеÑнеÑ»? РеÑли к ÑÑÐ¾Ð¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ ÐµÑе и Python... ЧÑÐ¾Ð±Ñ Ð¿Ð¾ÑÑвÑÑвоваÑÑ Ð²Ñе ÑÑо на пÑакÑике, погÑÑзимÑÑ ÑÐµÐ³Ð¾Ð´Ð½Ñ Ð² пÑÑÐ¸Ð½Ñ SQL-запÑоÑов и HTTP-оÑвеÑов вмеÑÑе Ñ '''СеÑгеем СÑпÑÑновÑм'''.'' |
− | + | ÐÑ Ñже видели, ÑÑо Python пÑекÑаÑно подÑ
Ð¾Ð´Ð¸Ñ Ð´Ð»Ñ ÑабоÑÑ Ñ ÑекÑÑом. Ð ÑÑо Ñакое инÑеÑнеÑ-ÑÑÑаниÑÑ, коÑоÑÑе Ð¼Ð¸Ð»Ð»Ð¸Ð¾Ð½Ñ ÑеÑвеÑов Apache ежедневно миллиаÑдами оÑдаÑÑ Ð½Ð° ÑаÑÑеÑзание наÑим бÑаÑзеÑам? Ðо ÑÑÑи, ÑÐ¾Ñ Ð¶Ðµ ÑекÑÑ, ÑолÑко немножко «гипеÑ»... РзнаÑиÑ, еÑли нам нÑжно бÑÐ´ÐµÑ ÑоÑмиÑоваÑÑ html-ÑÑÑаниÑÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑки, Ñо Python пÑекÑаÑно Ñ ÑÑим ÑпÑавиÑÑÑ. РникакиÑ
пÑепÑÑÑÑвий Ð´Ð»Ñ ÑазÑабоÑки на нем CGI-ÑÑенаÑиев не ÑÑÑеÑÑвÑÐµÑ â web-ÑеÑвеÑÑ, по болÑÑÐ¾Ð¼Ñ ÑÑеÑÑ, безÑазлиÑно, как именно вÑполнÑеÑÑÑ ÑкÑÐ¸Ð¿Ñ Ð¸ на каком ÑзÑке он ÑазÑабоÑан: лиÑÑ Ð±Ñ Ð¾Ð½ Ñмел ÑиÑаÑÑ Ð´Ð°Ð½Ð½Ñе из поÑока ввода и пеÑеменнÑÑ
окÑÑÐ¶ÐµÐ½Ð¸Ñ Ð´Ð° оÑдаваÑÑ ÑекÑÑ Ð² ÑÑандаÑÑнÑй вÑÑ
одной поÑок. | |
− | + | ÐпÑоÑем, еÑли Ð²Ñ Ð¶Ð°Ð¶Ð´ÐµÑе ÑкоÑоÑÑи, Ñо к ваÑим ÑÑлÑгам mod_Python, да и в Ñежиме FastCGI Python ÑабоÑаÑÑ ÑмееÑ. Ðо ÑейÑÐ°Ñ Ñ Ð½Ð°Ñ ÑÐ°Ð·Ð³Ð¾Ð²Ð¾Ñ Ð²Ñе же не о наÑÑÑойкаÑ
CGI, а о Python, Ñак ÑÑо веÑнемÑÑ Ðº ÑомÑ, Ñади Ñего Ð¼Ñ ÑÑÑ ÑÑаÑÑÑ Ð½Ð°Ñали. | |
− | === | + | === ÐоÑÑановка задаÑи === |
− | + | С лÑбÑм вопÑоÑом лÑÑÑе вÑего ÑазбиÑаÑÑÑÑ Ð½Ð° пÑакÑиÑеÑком пÑимеÑе. ÐоÑÑÐ¾Ð¼Ñ Ð¼Ñ Ð±Ñдем «плÑÑаÑÑ» вокÑÑг неÑложного и, в обÑем-Ñо, доÑÑаÑоÑно баналÑного CGI-пÑиложениÑ: гоÑÑевой книги. Ðаодно ÑазбеÑемÑÑ Ñ Ñем, как Python взаимодейÑÑвÑÐµÑ Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ даннÑÑ
, где пÑедÑÑавлÑеÑÑÑ ÑазÑмнÑм Ñ
ÑаниÑÑ Ð²Ñе наÑи ÑообÑениÑ. | |
− | + | Ðо пÑежде Ñем пеÑейÑи к ÑаÑÑмоÑÑÐµÐ½Ð¸Ñ ÐºÐ¾Ð´Ð° (Ð²Ñ Ð½Ð°Ð¹Ð´ÐµÑе его Ñеликом на наÑем диÑке), полезно бÑÐ´ÐµÑ Ð´Ð°ÑÑ ÐºÐ¾Ðµ-какÑÑ Ð²Ð²Ð¾Ð´Ð½ÑÑ Ð¸Ð½ÑоÑмаÑиÑ. | |
− | === | + | === УнивеÑÑалÑное «междÑмоÑдÑе» CGI === |
− | CGI (Common Gateway Interface, | + | CGI (Common Gateway Interface, обÑий ÑлÑзовой инÑеÑÑейÑ) бÑл ÑазÑабоÑан как ÑÑедÑÑво взаимодейÑÑÐ²Ð¸Ñ HTTP-ÑеÑвеÑа Ñ Ð¿ÑогÑаммами, коÑоÑÑе могÑÑ Ð·Ð°Ð¿ÑÑкаÑÑÑÑ Ð² опеÑаÑионной ÑиÑÑеме. ÐÑли говоÑиÑÑ ÑпÑоÑенно, Ñо CGI, пеÑÐµÐ´Ð°Ð²Ð°Ñ ÑпÑавление Ñакой пÑогÑамме (обÑÑно иÑ
именÑÑÑ cgi-ÑÑенаÑиÑми, Ñ
оÑÑ ÑÑо вполне Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ двоиÑнÑй Ñайл, ÑазÑабоÑаннÑй на C/C++), ÑоÑмиÑÑÐµÑ Ð´Ð»Ñ Ð½ÐµÐµ опÑеделенное окÑÑжение. Ð ÑаÑÑноÑÑи, паÑамеÑÑÑ HTTP-запÑоÑа, полÑÑенного Ð¾Ñ ÐºÐ»Ð¸ÐµÐ½Ñа, могÑÑ Ð¿Ð¾Ð¼ÐµÑаÑÑÑÑ Ð² опÑеделеннÑе пеÑеменнÑе окÑÑÐ¶ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ пеÑедаваÑÑÑÑ cgi-пÑогÑамме как аÑгÑменÑÑ Ð¸Ð»Ð¸ как вÑ
одной поÑок (STDIN). РоÑÐ²ÐµÑ HTTP-ÑеÑÐ²ÐµÑ Ð¶Ð´ÐµÑ Ð´Ð°Ð½Ð½Ñе, коÑоÑÑе cgi-пÑогÑамма должна вÑдаÑÑ Ð² ÑÑандаÑÑнÑй вÑÑ
одной поÑок (STDOUT), и пеÑÐµÐ´Ð°ÐµÑ Ð¸Ñ
клиенÑÑ. |
− | + | Таким обÑазом, вÑе, ÑÑо ÑÑебÑеÑÑÑ Ð¾Ñ cgi-пÑогÑаммÑ, ÑÑо ÑпоÑобноÑÑÑ Ð¿Ð¾Ð»ÑÑаÑÑ Ð½ÐµÐ¾Ð±Ñ
одимÑÑ Ð´Ð»Ñ ÑабоÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¸Ð· ÑоÑмиÑÑемой HTTP-ÑеÑвеÑом ÑÑÐµÐ´Ñ Ð¸ возвÑаÑаÑÑ Ð¾ÑвеÑнÑе даннÑе, ÑооÑвеÑÑÑвÑÑÑие пÑоÑÐ¾ÐºÐ¾Ð»Ñ HTTP, ÑÑÐ¾Ð±Ñ web-ÐºÐ»Ð¸ÐµÐ½Ñ Ð·Ð½Ð°Ð», ÑÑо Ñ Ð½Ð¸Ð¼Ð¸ делаÑÑ. | |
− | === | + | === УÑимÑÑ Ð¿Ð¾ÑÑлаÑÑ === |
− | + | ÐаÑнем Ñ ÑоÑмиÑÐ¾Ð²Ð°Ð½Ð¸Ñ HTTP-оÑвеÑа. ЧÑÐ¾Ð±Ñ Ð±ÑаÑÐ·ÐµÑ ÐºÐ»Ð¸ÐµÐ½Ñа мог его пÑавилÑно обÑабоÑаÑÑ, он должен ÑоÑÑоÑÑÑ Ð¸Ð· заголовка и Ñела, ÑазделеннÑÑ
пÑÑÑой ÑÑÑокой. Рзаголовке пеÑедаеÑÑÑ Ð½ÐµÐ¾Ð±Ñ
Ð¾Ð´Ð¸Ð¼Ð°Ñ ÑлÑÐ¶ÐµÐ±Ð½Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ, напÑимеÑ, Ñип ÑодеÑжимого, его кодиÑовка, Ñказание бÑаÑзеÑÑ Ð·Ð°Ð¿ÑоÑиÑÑ Ð´ÑÑгой ÑеÑÑÑÑ (Ñак назÑваемое пеÑенапÑавление), и Ñ.д. ÐÑоÑÑейÑий cgi-ÑÑенаÑий на ÑзÑке Python Ð¼Ð¾Ð¶ÐµÑ Ð²ÑглÑдеÑÑ Ñак: | |
<source lang="python"> | <source lang="python"> | ||
Строка 25: | Строка 26: | ||
# -*- coding: utf-8 -*- | # -*- coding: utf-8 -*- | ||
print 'Content-Type: text/html\n' | print 'Content-Type: text/html\n' | ||
− | print '<H3> | + | print '<H3>ÐÑли Ð²Ñ ÑÑо видиÑе, знаÑÐ¸Ñ Ð²Ñе ÑабоÑаеÑ</H3>' |
</source> | </source> | ||
− | + | ÐеÑвÑм опеÑаÑоÑом print Ð¼Ñ ÑоÑмиÑÑем минималÑно необÑ
одимÑй заголовок â бÑаÑÐ·ÐµÑ ÐºÐ»Ð¸ÐµÐ½Ñа обÑзаÑелÑно должен знаÑÑ, каков Ñип пеÑеÑÑлаемÑÑ
ÐµÐ¼Ñ Ð´Ð°Ð½Ð½ÑÑ
(в наÑем ÑлÑÑае ÑÑо пÑоÑÑой ÑекÑÑ, ÑооÑвеÑÑÑвÑÑÑий ÑоÑмаÑÑ HTML). Ðе забÑвайÑе о дополниÑелÑном пеÑеводе ÑÑÑоки \n, необÑ
одимом Ð´Ð»Ñ Ð¾ÑÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° Ð¾Ñ Ñела оÑвеÑа. ÐÑ Ð¸ далее Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе пеÑедаваÑÑ Ð»Ñбой HTML-код. | |
− | + | ÐналогиÑно могÑÑ Ð¿ÐµÑедаваÑÑÑÑ Ð»ÑбÑе обÑекÑÑ, поддеÑживаемÑе клиенÑом: изобÑажениÑ, звÑковÑе ÑайлÑ, css-ÑаблиÑÑ Ð¸ Ñ.д. Ðлавное, ÑÑÐ¾Ð±Ñ Ð·Ð½Ð°Ñение Ð¿Ð¾Ð»Ñ Content-Type (именÑемое Ñакже MIME-Ñипом) ÑооÑвеÑÑÑвовало ÑодеÑжимомÑ. | |
− | === | + | === ÐдеÑÑ Ð¸Ð³ÑаÑÑ, здеÑÑ Ð½Ðµ игÑаÑÑ... === |
− | + | Ðднако какой ÑмÑÑл поÑÑÑаÑÑ ÑоÑмиÑование ÑÑаÑиÑеÑкиÑ
, по ÑÑÑи, ÑÑÑÐ°Ð½Ð¸Ñ cgi-ÑÑенаÑиÑ, еÑли Ñам HTTP-ÑеÑÐ²ÐµÑ ÑпÑавиÑÑÑ Ñ ÑÑим намного лÑÑÑе? РобÑем-Ñо никакого. Разве ÑÑо Ð´Ð»Ñ Ð¾Ð±Ñего ÑазвиÑиÑ... Ð Ð²Ð¾Ñ Ð² Ñем CGI по-наÑÑоÑÑÐµÐ¼Ñ Ñилен, Ñак ÑÑо в ÑоÑмиÑовании динамиÑеÑкиÑ
ÑÑÑаниÑ, ÑодеÑжимое коÑоÑÑÑ
завиÑÐ¸Ñ Ð¾Ñ Ð¸Ð½ÑоÑмаÑии, пеÑеданной полÑзоваÑелем. | |
− | + | ÐÑоÑокол HTTP пÑедÑÑмаÑÑÐ¸Ð²Ð°ÐµÑ Ð½ÐµÑколÑко ÑпоÑобов пеÑедаÑи инÑоÑмаÑии Ð¾Ñ ÐºÐ»Ð¸ÐµÐ½Ñа на ÑеÑвеÑ, назÑваемÑÑ
меÑодами. Ðаиболее попÑлÑÑнÑе из ниÑ
â GET, POST, PUT и HEAD. | |
− | + | ÐеÑод GET позволÑÐµÑ Ð²ÑÑавлÑÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð² URL, Ñо еÑÑÑ Ð² ÑÑÑÐ¾ÐºÑ Ð°Ð´ÑеÑа запÑаÑиваемого ÑеÑÑÑÑа. Ðогда «ЯндекÑ» веÑÐ½ÐµÑ Ð²Ð°Ð¼ ÑпиÑок иÑкомÑÑ
ÑÑÑаниÑ, поÑмоÑÑиÑе на адÑеÑнÑÑ ÑÑÑÐ¾ÐºÑ Ð² бÑаÑзеÑе â Ð²Ð¾Ñ Ñак даннÑе и пеÑедаÑÑÑÑ Ð¼ÐµÑодом GET. ÐÑÑаÑи, обÑаÑиÑе внимание на Ñо, как вÑе ÑÑо кодиÑÑеÑÑÑ, оÑобенно еÑли Ð²Ñ Ð¸Ñкали какое-Ñо ÑÑÑÑкое Ñлово. | |
− | + | ÐÑли на ÑеÑÐ²ÐµÑ ÑÑебÑеÑÑÑ Ð¿ÐµÑедаÑÑ Ð±Ð¾Ð»ÑÑий обÑем инÑоÑмаÑии, или ее желаÑелÑно ÑкÑÑÑÑ Ð¾Ñ Ð»ÑбопÑÑнÑÑ
глаз, иÑполÑзÑеÑÑÑ Ð´ÑÑгой меÑод â POST. Рданном ÑлÑÑае в заголовке пеÑедаеÑÑÑ Ð»Ð¸ÑÑ ÑÐ°Ð·Ð¼ÐµÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑкиÑ
даннÑÑ
, а Ñами даннÑе пеÑеÑÑлаÑÑÑÑ Ð² Ñеле запÑоÑа. | |
− | + | ÐеÑод PUT пÑедназнаÑаеÑÑÑ Ð´Ð»Ñ ÑазмеÑÐµÐ½Ð¸Ñ ÑеÑÑÑÑов на ÑеÑвеÑе и по ÑообÑажениÑм безопаÑноÑÑи пÑакÑиÑеÑки не иÑполÑзÑеÑÑÑ. ÐÑ Ð¸, наконеÑ, меÑод HEAD оÑÐµÐ½Ñ Ð¿Ð¾Ñ
ож на GET, за Ñем иÑклÑÑением, ÑÑо ÑеÑÐ²ÐµÑ Ð² оÑÐ²ÐµÑ Ð½Ð° Ñакой запÑÐ¾Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ Ð½Ðµ веÑÑ ÑеÑÑÑÑ, а лиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ нем, ÑакÑÑ ÐºÐ°Ðº даÑа поÑледнего изменениÑ, помеÑаемÑÑ Ð² заголовке. ÐбÑÑно иÑполÑзÑеÑÑÑ Ð¿ÑокÑи-ÑеÑвеÑами Ð´Ð»Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Â«ÑвежеÑÑи» имеÑÑиÑ
ÑÑ Ñ Ð½Ð¸Ñ
даннÑÑ
â ÑÑÐ¾Ð¸Ñ Ð»Ð¸ запÑаÑиваÑÑ ÑеÑÑÑÑ Ð¿Ð¾Ð²ÑоÑно или можно веÑнÑÑÑ ÐºÐ»Ð¸ÐµÐ½ÑÑ Ñо, ÑÑо еÑÑÑ Ð² кÑÑе. | |
− | + | ÐпÑÐµÐ´ÐµÐ»ÐµÐ½Ð½Ð°Ñ ÑложноÑÑÑ Ð´Ð»Ñ ÑазÑабоÑÑика cgi-ÑÑенаÑÐ¸Ñ Ð·Ð°ÐºÐ»ÑÑаеÑÑÑ Ð² Ñом, ÑÑо даннÑе, оÑпÑавленнÑе ÑазлиÑнÑми меÑодами, пеÑедаÑÑÑÑ Ð² ÑÑенаÑий по-ÑазномÑ. Так, инÑоÑмаÑиÑ, поÑÑÑпивÑÐ°Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ POST, подаеÑÑÑ Ð½Ð° ÑÑандаÑÑнÑй вÑ
од ÑÑенаÑÐ¸Ñ Ð¸ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑÑиÑана оÑÑÑда, напÑимеÑ, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ sys.stdin.read(size) или даже ÑÑнкÑией raw_input() (Ñ
оÑÑ Ð²Ð¾ вÑоÑом ÑлÑÑае Ñложнее конÑÑолиÑоваÑÑ Ð¾Ð±Ñем пÑинимаемÑÑ
даннÑÑ
). ÐолиÑеÑÑво байÑ, коÑоÑÑе ÑÑебÑеÑÑÑ ÑÑиÑаÑÑ, можно полÑÑиÑÑ Ð¸Ð· пеÑеменной окÑÑÐ¶ÐµÐ½Ð¸Ñ CONTENT_LENGTH (напÑимеÑ, Ñак: size = os.environ['CONTENT_LENGTH']). | |
− | + | ÐÑли ÐºÐ»Ð¸ÐµÐ½Ñ Ð¸ÑполÑзÑÐµÑ Ð¼ÐµÑод GET, Ñо даннÑе поÑÑÑпÑÑ Ð² ÑÑенаÑий ÑеÑез пеÑеменнÑÑ ÑÑÐµÐ´Ñ QUERY_STRING. ÐеÑод, коÑоÑÑм даннÑе пеÑÐµÐ´Ð°Ð½Ñ (нÑжно же как-Ñо ÑазобÑаÑÑÑÑ, где иÑ
иÑкаÑÑ) можно вÑегда полÑÑиÑÑ Ð¸Ð· REQUEST_METHOD. | |
− | + | ÐÑÑÑ ÐµÑе один оÑобÑй ÑлÑÑай. ÐÑли даннÑе пеÑедаÑÑÑÑ Ð¼ÐµÑодом GET, но Ñ Ð¸ÑполÑзованием «индекÑного» ÑоÑмаÑа, коÑоÑÑй ÑоÑмиÑÑеÑÑÑ Ñегом <ISINDEX>, Ñо в ÑÑом ÑлÑÑае они кодиÑÑÑÑÑÑ Ð½Ðµ в виде «пеÑеменнаÑ=знаÑение&пеÑеменнаÑ=знаÑение&...», а как «знаÑение+знаÑение+...». Ð cgi-ÑÑенаÑÐ¸Ñ Ð¾Ð½Ð¸ бÑдÑÑ Ð¿ÐµÑеданÑ, помимо QUERY_STRING, ÑеÑез аÑгÑменÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð¾Ð¹ ÑÑÑоки, как еÑли Ð±Ñ ÑÑенаÑий вÑзÑвалÑÑ Ñакой командой: | |
script.cgi arg1 arg2 arg3 | script.cgi arg1 arg2 arg3 | ||
− | + | То еÑÑÑ, на ÑÑÐ¾Ñ Ñаз полÑзоваÑелÑÑкие даннÑе можно бÑÐ´ÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑ ÐºÐ°Ðº sys.argv[1] и Ñ.д. | |
− | + | Ðак видиÑе, огÑомное ÑиÑло ваÑианÑов, пÑедÑÑмоÑÑеннÑÑ
CGI-инÑеÑÑейÑом, коÑоÑÑе вÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑÑÑÐµÐ½Ñ Ð¿Ñи ÑазÑабоÑке ÑÑенаÑиÑ, Ð¼Ð¾Ð¶ÐµÑ Ð²ÑзваÑÑ Ð½ÐµÑвнÑй Ñик даже Ñ Ð¾Ð¿ÑÑнÑÑ
пÑогÑаммиÑÑов, коÑоÑÑе и во Ñне поÑиÑ
онÑÐºÑ Ð½Ð°Ð±Ð¸Ð²Ð°ÑÑ Ð¿Ð¾ подÑÑке какой-Ñо код. РеÑли еÑе вÑпомниÑÑ, ÑÑо даннÑе пеÑедаÑÑÑÑ Ð² закодиÑованном виде (ÑÑо англиÑанам Ñ
оÑоÑо â взÑл знаÑение пеÑеменной и ÑабоÑай, а нам-Ñо Ñ Ð²Ð°Ð¼Ð¸ ÑÑо знаÑение веÑнеÑÑÑ Ð² виде %EC%E4%E0), да еÑе и о пÑовеÑке ÑÑиÑ
даннÑÑ
нÑжно позабоÑиÑÑÑÑ, ÑÑÐ¾Ð±Ñ ÐºÐ°ÐºÐ¾Ð¹-нибÑÐ´Ñ Ð½Ð°ÑинаÑÑий Ñ
Ð°ÐºÐµÑ Ð½Ðµ попÑÑалÑÑ Ð·Ð°ÑÑавиÑÑ Ð½Ð°Ñ ÑеÑÐ²ÐµÑ ÑабоÑаÑÑ Ð¿Ð¾-ÑвоемÑ... ÐеÑ, обо вÑем ÑÑом лÑÑÑе и не вÑпоминаÑÑ. Ðлаго Ñ Ð½Ð°Ñ ÐµÑÑÑ Ð¼Ð¾Ð´ÑÐ»Ñ cgi, в коÑоÑом вÑе ÑÑо Ñже Ñделано! | |
− | + | Ðо о нем â ÑÑÑÑ Ð¿Ð¾Ð·Ð¶Ðµ. СнаÑала паÑÑ Ñлов нÑжно ÑказаÑÑ Ð¾ HTML-ÑоÑмаÑ
. | |
− | === | + | === ФоÑмиÑÑем ÑоÑÐ¼Ñ === |
− | + | ЧÑÐ¾Ð±Ñ Ð²Ð°Ð¼ бÑло пÑоÑе понÑÑÑ ÑаÑÑмаÑÑиваемÑй ÑÐµÐ³Ð¾Ð´Ð½Ñ Ð¿ÑимеÑ, коÑоÑко ÑÐºÐ°Ð¶Ñ Ð¿Ñо Ñо, как же ÐºÐ»Ð¸ÐµÐ½Ñ Ð²ÑполнÑÐµÑ Ð¿ÐµÑедаÑÑ Ð´Ð°Ð½Ð½ÑÑ
наÑÐµÐ¼Ñ cgi-ÑÑенаÑиÑ. ÐонеÑно, пÑодвинÑÑÑе полÑзоваÑели могÑÑ Ð½Ð°Ð±ÑаÑÑ GET-запÑÐ¾Ñ Ð²ÑÑÑнÑÑ Ð² адÑеÑной ÑÑÑоке бÑаÑзеÑа. ХоÑÑ ÑÑо мелоÑиÑÑÑÑ â Ð²ÐµÐ´Ñ Ð¼Ð¾Ð¶Ð½Ð¾ же ÑÑоÑмиÑоваÑÑ Ð¸ POST-запÑоÑ, подклÑÑивÑиÑÑ ÑелнеÑом на 80-й поÑÑ! ÐпÑоÑем, обÑÑнÑе полÑзоваÑели пÑедпоÑиÑаÑÑ Ð±Ð¾Ð»ÐµÐµ понÑÑнÑе и «оÑÑзаемÑе» ÑпоÑобÑ, напÑимеÑ, ÑоÑмÑ. | |
− | + | Ðак они вÑглÑдÑÑ, дÑмаÑ, каждÑй знаеÑ. СоздаÑÑÑÑ Ð¾Ð½Ð¸ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ñега <FORM>, внÑÑÑи коÑоÑого добавлÑÑÑÑÑ Ñакие ÑлеменÑÑ, как <INPUT> (поле ввода) или <TEXTAREA> (многоÑÑÑоÑнÑй ÑедакÑоÑ). ÐÑим ÑлеменÑам, еÑли иÑ
даннÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿ÐµÑÐµÐ´Ð°Ð½Ñ Ð½Ð° ÑеÑвеÑ, пÑиÑваиваÑÑÑÑ Ð¸Ð¼ÐµÐ½Ð° Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð°ÑÑибÑÑа name. ÐаÑалÑное знаÑение задаеÑÑÑ Ð¿Ð°ÑамеÑÑом value и в далÑнейÑем Ð´Ð»Ñ Â«ÑедакÑиÑÑемÑÑ
» полей Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¾ полÑзоваÑелем. Ðогда полÑзоваÑÐµÐ»Ñ Ð½Ð°Ð¶Ð¸Ð¼Ð°ÐµÑ ÐºÐ½Ð¾Ð¿ÐºÑ Â«ÐÑпÑавиÑÑ» (надпиÑÑ Ð½Ð° ней, в пÑинÑипе, можно измениÑÑ), Ñо бÑаÑÐ·ÐµÑ Ð¾Ð±ÑединÑÐµÑ Ð²Ñе даннÑе полей в паÑÑ name=value, ÑазделÑÑ Ð¸Ñ
Ñимволом &. ÐаÑем полÑÑÐµÐ½Ð½Ð°Ñ Ñаким обÑазом ÑÑÑока пеÑедаеÑÑÑ Ð½Ð° ÑеÑÐ²ÐµÑ Ð¼ÐµÑодом, ÑказаннÑм в аÑÑибÑÑе method Ñега <FORM>. ÐÑÑÑ Ðº ÑÑенаÑиÑ, коÑоÑÑй бÑÐ´ÐµÑ Ð·Ð°Ð½Ð¸Ð¼Ð°ÑÑÑÑ ÐµÐµ обÑабоÑкой, задаеÑÑÑ Ð°ÑÑибÑÑом action ÑÑого же Ñега. ÐÑли action не задан, Ñо даннÑе пеÑедаÑÑÑÑ ÑайлÑ, ÑÑоÑмиÑовавÑÐµÐ¼Ñ ÑекÑÑÑÑ ÑÑÑаниÑкÑ. | |
− | + | ÐÑли ÑÑо-Ñо не ÑовÑем понÑÑно, обÑаÑиÑеÑÑ Ðº ÐºÐ¾Ð´Ñ ÑазÑабаÑÑваемой гоÑÑевой книги, коÑоÑÑй пÑиведен ниже. | |
− | === | + | === ÐÐ°Ñ ÑпаÑиÑÐµÐ»Ñ â модÑÐ»Ñ cgi === |
− | + | ÐозвÑаÑаемÑÑ Ðº обÑабоÑке вÑего ÑÑого добÑа, коÑоÑое ÑоÑни полÑзоваÑелей Ñже гоÑÐ¾Ð²Ñ Ð¾Ð±ÑÑÑиÑÑ Ð½Ð° Ð½Ð°Ñ Ð±ÐµÐ´Ð½Ñй ÑÑенаÑий. ÐÑ ÑеÑили воÑполÑзоваÑÑÑÑ ÑÑандаÑÑнÑми ÑÑедÑÑвами Python, и здеÑÑ Ð²Ñе дейÑÑвиÑелÑно оÑÐµÐ½Ñ Ð¿ÑоÑÑо â импоÑÑиÑÑйÑе модÑÐ»Ñ cgi и, Ñоздав обÑÐµÐºÑ ÐºÐ»Ð°ÑÑа FieldStorage, Ð²Ñ Ð¿Ð¾Ð»ÑÑиÑе ÑеÑез него доÑÑÑп ко вÑем даннÑм, пеÑеданнÑм полÑзоваÑелем, незавиÑимо Ð¾Ñ Ð¸ÑполÑзÑемого меÑода: | |
<source lang="python"> | <source lang="python"> | ||
Строка 71: | Строка 72: | ||
data = cgi.FieldStorage() | data = cgi.FieldStorage() | ||
for entry in data.keys(): | for entry in data.keys(): | ||
− | print ' | + | print 'ÐеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ %s Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°Ñение %s' % (entry, data[entry].value) |
</source> | </source> | ||
− | + | ÐÑли вам нÑжно полÑÑиÑÑ Ð·Ð½Ð°Ñение опÑеделенного полÑ, ÑÑо делаеÑÑÑ Ñак: | |
<source lang="python"> | <source lang="python"> | ||
Строка 80: | Строка 81: | ||
</source> | </source> | ||
− | + | Ðомимо полÑзоваÑелÑÑкиÑ
даннÑÑ
, обÑÐµÐºÑ ÐºÐ»Ð°ÑÑа FieldStorage ÑодеÑÐ¶Ð¸Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¸ о полÑÑ
заголовка (в наÑем пÑимеÑе иÑ
можно полÑÑиÑÑ Ð¸Ð· ÑловаÑÑ data.headers). MIME-Ñип даннÑÑ
(пеÑедаваемÑй полем заголовка Content-Type) можно полÑÑиÑÑ Ð¸Ð· аÑÑибÑÑа data.type. ЧеÑез ÑÑÐ¾Ñ Ð¶Ðµ обÑÐµÐºÑ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²Ñполнена и загÑÑзка Ñайла. | |
− | + | С помоÑÑÑ Ð¼ÐµÑодов keys() и has_key() можно вÑполнÑÑÑ Ð¾Ð±ÑабоÑÐºÑ Ð¿Ð¾Ð»ÑÑеннÑÑ
даннÑÑ
в Ñикле и пÑовеÑÑÑÑ Ð½Ð°Ð»Ð¸Ñие Ñой или иной пеÑеменной. ÐÑÑаÑи говоÑÑ, пÑовеÑÑÑÑ Ð½Ð°Ð»Ð¸Ñие пеÑеменной во вÑ
однÑÑ
даннÑÑ
, пÑежде Ñем пÑиÑÑÑпаÑÑ Ðº иÑ
обÑабоÑке, нÑжно непÑеменно â Ð²ÐµÐ´Ñ Ð·Ð°Ð¿ÑÐ¾Ñ ÑоÑмиÑÑеÑÑÑ ÐºÐ»Ð¸ÐµÐ½Ñом, а кÑо знаеÑ, ÑÑо Ñ Ð½ÐµÐ³Ð¾ на Ñме? | |
− | === | + | === ÐазиÑÑем даннÑе === |
− | + | ÐÑак, полÑÑаÑÑ Ð´Ð°Ð½Ð½Ñе Ð¾Ñ ÐºÐ»Ð¸ÐµÐ½Ñа Ð¼Ñ Ð½Ð°ÑÑилиÑÑ. ÐÑпÑавлÑÑÑ Ñоже Ñмеем. ÐÑÑалоÑÑ Ð¿ÑидÑмаÑÑ, как ÑÑи даннÑе лÑÑÑе вÑего Ñ
ÑаниÑÑ. ÐонеÑно, Ð´Ð»Ñ Ð½ÐµÑложной гоÑÑевой книги Ñ Ð½ÐµÐ±Ð¾Ð»ÑÑой нагÑÑзкой вполне Ñ
ваÑило Ð±Ñ Ð¸ ÑекÑÑовÑÑ
Ñайлов. ÐÑавда, Ñам еÑÑÑ Ñвои ÑложноÑÑи â еÑли ÑÑÐ°Ð·Ñ Ð¿ÑÑÑ Ñеловек заÑ
оÑÑÑ Ð²ÑÑказаÑÑ Ñвое мнение о ваÑей кÑÑÑейÑей домаÑней ÑÑÑаниÑке, Ñо ÑÑенаÑÐ¸Ñ Ð¿ÑидеÑÑÑ ÐºÐ°ÐºÐ¸Ð¼-Ñо обÑазом ÑегÑлиÑоваÑÑ Ð´Ð¾ÑÑÑп к ÑайлÑ-Ñ
ÑанилиÑÑ (как минимÑм, обÑабаÑÑваÑÑ ÑиÑÑаÑиÑ, еÑли Ñайл Ñже оÑкÑÑÑ Ð½Ð° запиÑÑ Ð´ÑÑгим ÑкземплÑÑом ÑÑенаÑиÑ). Ðо заÑем нам вÑе ÑÑи головнÑе боли? ÐÑли Ð¼Ñ Ñак ловко оÑвеÑÑелиÑÑ Ð¾Ñ Ð½ÐµÐ¾Ð±Ñ
одимоÑÑи вÑÑÑнÑÑ ÑазбиÑаÑÑ HTTP-запÑоÑÑ, Ñо неÑжели не найдем ÑÑо-Ñо подÑ
одÑÑее на ÑÑÐ¾Ñ Ñаз? | |
− | + | ÐонеÑно, найдем! Ð ÑÑо «ÑÑо-Ñо» назÑваеÑÑÑ ÑиÑÑемой ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ даннÑÑ
(в пÑоÑÑоÑеÑÑе â СУÐÐ). ТепеÑÑ Ð½Ð°Ñе дело â оÑпÑавиÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð¸ полÑÑиÑÑ Ð¾ÑвеÑ. ÐÑе оÑÑалÑное â Ñже не наÑа забоÑа. | |
− | + | ÐÐ»Ñ ÑÑого пÑимеÑа Ñ Ð²ÑбÑал в каÑеÑÑве «оÑвеÑÑÑвенного» за Ñ
Ñанение даннÑÑ
ÑеÑÐ²ÐµÑ Ð±Ð°Ð· даннÑÑ
PostgreSQL. ÐоÑколÑÐºÑ Ð¼Ñ Ð¿Ð¸Ñем Ð½Ñ Ð¾ÑÐµÐ½Ñ Ð¿ÑоÑÑÑÑ Ð³Ð¾ÑÑевÑÑ ÐºÐ½Ð¸Ð³Ñ, Ñо и ÑÑÑÑкÑÑÑа Ð±Ð°Ð·Ñ Ð±ÑÐ´ÐµÑ Ñ Ð½Ð°Ñ ÑлеменÑаÑной â одна ÑаблиÑа Ñ ÑÑÐµÐ¼Ñ Ð¿Ð¾Ð»Ñми: вÑÐµÐ¼Ñ Ð¿ÑбликаÑии ÑообÑениÑ, Ð¸Ð¼Ñ Ð°Ð²ÑоÑа и, ÑобÑÑвенно, Ñамо ÑообÑение: | |
admin@toshiba:~$ psql | admin@toshiba:~$ psql | ||
Строка 98: | Строка 99: | ||
CREATE DATABASE | CREATE DATABASE | ||
admin=# \connect guestbook | admin=# \connect guestbook | ||
− | + | ÐÑ Ð¿Ð¾Ð´ÑоединилиÑÑ Ðº базе даннÑÑ
"guestbook". | |
guestbook=# create table guestbook ( | guestbook=# create table guestbook ( | ||
guestbook(# datum timestamp, author varchar, message varchar); | guestbook(# datum timestamp, author varchar, message varchar); | ||
Строка 107: | Строка 108: | ||
admin@toshiba:~$ | admin@toshiba:~$ | ||
− | + | ÐожалÑй, единÑÑвенное, ÑÑо здеÑÑ Ð½Ñжно поÑÑниÑÑ, ÑÑо поÑÐµÐ¼Ñ Ð±Ð°Ð·Ðµ и ÑаблиÑе Ð¼Ñ Ð½Ð°Ð·Ð½Ð°Ñили владелÑÑем полÑзоваÑÐµÐ»Ñ www-data. ÐÑоÑÑо к ним бÑÐ´ÐµÑ Ð¾Ð±ÑаÑаÑÑÑÑ cgi-ÑÑенаÑий, ÑабоÑаÑÑий Ñ Ð¿Ñавами HTTP-ÑеÑвеÑа Apache, коÑоÑÑй, в ÑÐ²Ð¾Ñ Ð¾ÑеÑедÑ, иÑполнÑеÑÑÑ Ð¾Ñ Ð¸Ð¼ÐµÐ½Ð¸ данного полÑзоваÑÐµÐ»Ñ [в ваÑем диÑÑÑибÑÑиве он Ð¼Ð¾Ð¶ÐµÑ Ð½Ð°Ð·Ð²Ð°ÑÑÑÑ Ð¿Ð¾-дÑÑгомÑ, â пÑим. Ñед.]. Ð PostgreSQL по ÑмолÑÐ°Ð½Ð¸Ñ ÑÑебÑеÑ, ÑÑÐ¾Ð±Ñ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð² ÐÐ Ñовпадало Ñ ÐµÐ³Ð¾ ÑиÑÑемнÑм именем. Ðне ÑÑо кажеÑÑÑ Ð´Ð¾ÑÑаÑоÑно ÑдобнÑм, Ñ
оÑÑ Ð²Ñ, конеÑно, можеÑе поÑÑÑпиÑÑ Ð¿Ð¾-ÑвоемÑ. | |
− | === DB API | + | === DB API на ÑÑÑаже ÑниÑикаÑии === |
− | + | ÐÑÑалоÑÑ ÑазобÑаÑÑÑÑ, как же Python взаимодейÑÑвÑÐµÑ Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ даннÑÑ
. ÐÐ»Ñ ÑÑого Python пÑедоÑÑавлÑÐµÑ DB API â ÑпеÑиалÑнÑй инÑеÑÑейÑ, ÑниÑиÑиÑÑÑÑий Ð½Ð°Ð±Ð¾Ñ Ð¼ÐµÑодов, коÑоÑÑе бÑдÑÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾ ÑабоÑаÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо Ð¾Ñ Ñого, Ñ ÐºÐ°ÐºÐ¾Ð¹ СУÐÐ Ð¼Ñ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð´ÐµÐ¹ÑÑвÑем. ÐÐ»Ñ ÑабоÑÑ Ñ PostgreSQL нам понадобиÑÑÑ Ð¼Ð¾Ð´ÑÐ»Ñ PyPgSQL (в ÑÑандаÑÑной поÑÑавке его Ð¼Ð¾Ð¶ÐµÑ Ð½Ðµ оказаÑÑÑÑ, но Ð²Ð°Ñ Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑ Ð¿Ð°ÐºÐµÑов навеÑнÑка бÑÐ´ÐµÑ Ð² кÑÑÑе, как его ÑÑÑановиÑÑ; кÑÑаÑи, ÑÑо не единÑÑвеннÑй модÑÐ»Ñ â Ñ Ð²Ð°Ñ, возможно, бÑÐ´ÐµÑ PyGreSQL, коÑоÑÑй ÑабоÑÐ°ÐµÑ Ð½Ð¸ÑÑÑÑ Ð½Ð¸ Ñ
Ñже и Ñ Ñеми же ÑамÑми меÑодами). | |
− | DB API | + | DB API опÑеделÑÐµÑ ÑÑандаÑÑнÑе меÑÐ¾Ð´Ñ ÑабоÑÑ Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ даннÑÑ
, Ñак ÑÑо, какой Ð±Ñ Ð¼Ð¾Ð´ÑÐ»Ñ Ð²Ñ Ð½Ð¸ загÑÑзили и Ñ ÐºÐ°ÐºÐ¾Ð¹ Ð±Ñ Ð¡Ð£ÐРни ÑабоÑали (бÑÐ´Ñ Ñо MySQL, PostgreSQL, SQLite или ÑÑо-Ñо еÑе), менÑÑÑÑÑ Ð±ÑÐ´ÐµÑ ÑолÑко Ð¸Ð¼Ñ Ð¼Ð¾Ð´ÑлÑ. Ðлавное, ÑÑÐ¾Ð±Ñ Ð¸ÑполÑзÑемÑй модÑÐ»Ñ ÑооÑвеÑÑÑвовал DB API. РаÑÑмоÑÑим коÑоÑко оÑновнÑе меÑодÑ: |
<source lang="python"> | <source lang="python"> | ||
Строка 118: | Строка 119: | ||
</source> | </source> | ||
− | + | Так оÑÑÑеÑÑвлÑеÑÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑение к базе. РзавиÑимоÑÑи Ð¾Ñ ÑиÑÑаÑии, вам Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ ÑказаÑÑ ÑолÑко нÑжнÑе паÑамеÑÑÑ (напÑимеÑ, Ð¸Ð¼Ñ Ñ
оÑÑа 'localhost' подÑазÑмеваеÑÑÑ Ð¿Ð¾ ÑмолÑаниÑ). | |
<source lang="python"> | <source lang="python"> | ||
Строка 124: | Строка 125: | ||
</source> | </source> | ||
− | + | ÐÑÑÑоÑÑ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑÑÑ Ð´Ð°Ð»ÐµÐºÐ¾ не вÑеми СУÐÐ, но Ð´Ð»Ñ Ð¾Ð±ÑноÑÑи в DB API они Ð²Ð²ÐµÐ´ÐµÐ½Ñ Ð¸, в ÑлÑÑае необÑ
одимоÑÑи, Ð´Ð¾Ð»Ð¶Ð½Ñ ÑмÑлиÑоваÑÑÑÑ Ð¼Ð¾Ð´ÑлÑми ÑопÑÑÐ¶ÐµÐ½Ð¸Ñ Ð¸ÑкÑÑÑÑвенно. Так ÑÑо не забÑвайÑе оÑпÑавлÑÑÑ Ð²Ñе ваÑи запÑоÑÑ ÑеÑез кÑÑÑоÑ. | |
<source lang="python"> | <source lang="python"> | ||
Строка 130: | Строка 131: | ||
</source> | </source> | ||
− | + | Так вÑполнÑеÑÑÑ SQL-запÑоÑ. ÐÑли в ÑÑÑоке запÑоÑа иÑполÑзÑÑÑÑÑ Ð·Ð½Ð°ÐºÐ¾Ð¼ÐµÑÑа %s, Ñо вÑоÑÑм паÑамеÑÑом пеÑедаеÑÑÑ ÑпиÑок пеÑеменнÑÑ
-знаÑений, пÑиÑем в SQL-запÑоÑе знакомеÑÑа не ÑÑебÑеÑÑÑ Ð¾ÐºÑÑжаÑÑ Ð°Ð¿Ð¾ÑÑÑоÑами â модÑÐ»Ñ ÑÐ´ÐµÐ»Ð°ÐµÑ ÑÑо ÑамоÑÑоÑÑелÑно в завиÑимоÑÑи Ð¾Ñ | |
− | + | Ñипа пеÑеменной. | |
<source lang="python"> | <source lang="python"> | ||
Строка 137: | Строка 138: | ||
</source> | </source> | ||
− | + | ÐозвÑаÑÐ°ÐµÑ Ð´Ð²ÑмеÑнÑй ÑпиÑок (ÑÑÑоки â полÑ) полÑÑеннÑÑ
Ð¾Ñ Ð¡Ð£ÐРданнÑÑ
. СÑÑеÑÑвÑÑÑ Ð¸ дÑÑгие меÑодÑ, ознакомиÑÑÑÑ Ñ ÐºÐ¾ÑоÑÑми Ð²Ñ ÑможеÑе в докÑменÑаÑии или Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð·Ð½Ð°ÐºÐ¾Ð¼Ð¾Ð¹ вам ÑÑнкÑии dir() да паÑÑ-ÑÑойки неÑложнÑÑ
ÑкÑпеÑименÑов. | |
− | === | + | === ÐакÑеплÑем на пÑакÑике === |
− | + | ÐеÑейдем к ÑаÑÑмоÑÑÐµÐ½Ð¸Ñ Ð½Ð°Ñего пÑимеÑа. ÐаÑнем ÑÑандаÑÑно â Ñкажем кодиÑовкÑ, подклÑÑим нÑжнÑе модÑли: | |
<source lang="python"> | <source lang="python"> | ||
Строка 149: | Строка 150: | ||
</source> | </source> | ||
− | + | Ðалее, опÑеделим две ÑÑнкÑии. ÐеÑÐ²Ð°Ñ Ð±ÑÐ´ÐµÑ Ð¾ÑвеÑаÑÑ Ð·Ð° добавление нового ÑообÑÐµÐ½Ð¸Ñ Ð² базÑ: | |
<source lang="python"> | <source lang="python"> | ||
Строка 163: | Строка 164: | ||
</source> | </source> | ||
− | + | Ðак видиÑе, вÑе оÑÐµÐ½Ñ Ð´Ð°Ð¶Ðµ логиÑно: ÑÑÑанавливаем Ñоединение Ñ ÐÐ (поÑколÑÐºÑ Ð² наÑем ÑлÑÑае подклÑÑение вÑполнÑеÑÑÑ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ ÑекÑÑего ÑиÑÑемного полÑзоваÑелÑ, Ñо доÑÑаÑоÑно ÑказаÑÑ ÑолÑко Ð¸Ð¼Ñ Ð±Ð°Ð·Ñ), Ñоздаем кÑÑÑÐ¾Ñ (в PostgreSQL они не пÑименÑÑÑÑÑ, но они ÑмÑлиÑÑÑÑÑÑ ÐºÐ°Ð¶Ð´Ñм модÑлем, пÑеÑендÑÑÑим на ÑооÑвеÑÑÑвие DB API), вÑполнÑеÑÑÑ Ð·Ð°Ð¿ÑоÑ, закÑÑваеÑÑÑ ÐºÑÑÑоÑ, ÑикÑиÑÑÑÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ (PostgreSQL иÑполÑзÑÐµÑ ÑÑанзакÑии, поÑÑÐ¾Ð¼Ñ Ð²Ñполнение меÑода commit() обÑзаÑелÑно, инаÑе ваÑи Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ бÑдÑÑ ÑоÑ
ÑаненÑ), и, наконеÑ, закÑÑваем Ñамо Ñоединение Ñ Ð±Ð°Ð·Ð¾Ð¹. Рполе datum заноÑим знаÑение вÑÑÑоенной пеÑеменной PostgreSQL â now, коÑоÑÐ°Ñ ÐºÐ°Ð¶Ð´Ñй Ñаз заменÑеÑÑÑ ÑекÑÑим знаÑением даÑÑ Ð¸ вÑемени. | |
− | + | ÐÑ Ð¸ пеÑаÑÑ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° «Location» вÑполнÑеÑÑÑ Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ Ð¿ÐµÑенапÑавиÑÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð½Ð° ÑÑÐ¾Ñ Ð¶Ðµ ÑÑенаÑий, но Ñже без паÑамеÑÑов â Ð¼Ñ Ð¶Ðµ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°ÑÑ ÐºÐ»Ð¸ÐµÐ½ÑÑ, ÑÑо он на Ñамом деле ввел? (ЯкоÑÑ #form иÑполÑзÑеÑÑÑ, ÑÑÐ¾Ð±Ñ Ð°Ð²ÑомаÑиÑеÑки пÑокÑÑÑиÑÑ ÑÑÑаниÑÐºÑ Ð½Ð° поÑледнее ÑообÑение). | |
− | + | ÐÑоÑÐ°Ñ ÑÑнкÑÐ¸Ñ Ð±ÑÐ´ÐµÑ Ð¾ÑвеÑаÑÑ Ð·Ð° вÑвод на ÑкÑан Ñже оÑÑавленнÑÑ
в книге запиÑей, а Ñакже за ÑоÑмÑ, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÐºÐ¾ÑоÑой можно бÑÐ´ÐµÑ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ð¸ Ñвое вÑÑказÑвание: | |
<source lang="python"> | <source lang="python"> | ||
Строка 179: | Строка 180: | ||
</source> | </source> | ||
− | + | Ð ÑÑом ÑÑагменÑе Ð¼Ñ Ð²ÑбиÑаем вÑе ÑÑÑоки из наÑей ÑаблиÑÑ Ð´Ð°Ð½Ð½ÑÑ
, ÑоÑÑиÑÑÑ Ð¸Ñ
по даÑе. РезÑлÑÑÐ°Ñ ÑоÑ
ÑанÑеÑÑÑ Ð² пеÑеменной res, Ñ ÐºÐ¾ÑоÑой и бÑдем ÑабоÑаÑÑ. ТепеÑÑ Ð¾ÑÑалоÑÑ Ð»Ð¸ÑÑ Ð°ÐºÐºÑÑаÑненÑко ÑазложиÑÑ Ð½Ð°Ñи даннÑе по ÑаблиÑкам и вÑвеÑÑи иÑ
на ÑкÑан: | |
<source lang="python"> | <source lang="python"> | ||
print "Content-Type: text/html\n" | print "Content-Type: text/html\n" | ||
− | print "<H1 style='color:#7777FF'><U> | + | print "<H1 style='color:#7777FF'><U>ÐелÑкам к нам в гоÑÑи!</U></H1>" |
for item in res: | for item in res: | ||
print """<TABLE width='90%%'> | print """<TABLE width='90%%'> | ||
− | <TR><TD><SMALL> | + | <TR><TD><SMALL>ТоваÑÐ¸Ñ <B>%s</B> поведалнам ÑледÑÑÑее:</SMALL> |
<TD align='right'><SMALL>%s</SMALL> | <TD align='right'><SMALL>%s</SMALL> | ||
<TR><TD style='background-color:#DDDDFF' colspan='2'>%s | <TR><TD style='background-color:#DDDDFF' colspan='2'>%s | ||
</TABLE>""" % (item[1], str(item[0])[:19], item[2]) | </TABLE>""" % (item[1], str(item[0])[:19], item[2]) | ||
− | print "<HR><A name='form'><H3> | + | print "<HR><A name='form'><H3>ÐÑиÑоединÑйÑеÑÑ Ðº диÑкÑÑÑии:</H3>" |
print """<FORM method='GET'> | print """<FORM method='GET'> | ||
− | + | ÐаÑе имÑ: <INPUT type='text' name='author'><BR> | |
− | + | ЧÑо Ð²Ñ Ð´ÑмаеÑе по ÑÑÐ¾Ð¼Ñ Ð¿Ð¾Ð²Ð¾Ð´Ñ:<BR> | |
<TEXTAREA name='message' rows='5' cols='80'></TEXTAREA><BR> | <TEXTAREA name='message' rows='5' cols='80'></TEXTAREA><BR> | ||
− | <INPUT type='submit' value=' | + | <INPUT type='submit' value='ÐÑпÑавиÑÑ'> |
</FORM>""" | </FORM>""" | ||
</source> | </source> | ||
<div id="img"></div> | <div id="img"></div> | ||
− | [[ | + | [[ÐзобÑажение:Img 83 81 1.png|thumb|Ðи Ñмайликов, ни BB-кода, ни даже логоÑипа... ÐаÑо Ð¼Ñ Ñделали ÑÑÑ Ð³Ð¾ÑÑевÑÑ Ð·Ð° 10 минÑÑ!]] |
− | + | СмÑÑл конÑÑÑÑкÑии str(item[0])[:19] заклÑÑаеÑÑÑ Ð² Ñом, ÑÑÐ¾Ð±Ñ Ð² ÑÑÑоке вÑемени оÑÑеÑÑ Ð½ÐµÐ½ÑжнÑе нам миллиÑекÑндÑ, коÑоÑÑе ÑоÑ
ÑанÑÑÑÑÑ Ð² поле Ñипа timestamp. ÐоÑле вÑеÑ
опÑбликованнÑÑ
ÑообÑений вÑводим ÑоÑÐ¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾, ÑÑÐ¾Ð±Ñ ÐºÐ°Ð¶Ð´Ñй мог пÑиÑоединиÑÑÑÑ Ðº наÑей диÑкÑÑÑии. ÐÑÑаÑи, в Ñеге <FORM> Ð¼Ñ Ð½Ðµ Ñказали паÑамеÑÑ action, поÑколÑÐºÑ Ð´Ð°Ð½Ð½Ñе бÑдÑÑ Ð¿ÐµÑедаваÑÑÑÑ Ð½Ð° обÑабоÑÐºÑ ÑÑÐ¾Ð¼Ñ Ð¶Ðµ ÑÑенаÑÐ¸Ñ (благодаÑÑ ÑÐµÐ¼Ñ Ð¸Ð¼Ñ ÑÑенаÑÐ¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ пÑиÑвоиÑÑ Ð»Ñбое). | |
− | + | ÐаконеÑ, поÑледний ÑÑагменÑ: | |
<source lang="python"> | <source lang="python"> | ||
Строка 216: | Строка 217: | ||
</source> | </source> | ||
− | + | Создаем FieldStorage-обÑекÑ, и еÑли в нем еÑÑÑ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð½Ñе Ð¿Ð¾Ð»Ñ message и author (Ñо еÑÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð±Ñл ÑÑоÑмиÑован из заполненной полÑзоваÑелем ÑоÑмÑ), Ñо, немножко иÑ
обÑабоÑав (ÑÑнкÑÐ¸Ñ cgi.escape() заменÑÐµÑ Ð²Ñе «неблагонадежнÑе» ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ â напÑимеÑ, < â иÑ
ÑÑандаÑÑнÑми SGML-ÑÑÑноÑÑÑми, в данном ÑлÑÑае â <), пеÑедаем ÑÑнкÑии addMessage(). ÐбÑабоÑка нÑжна Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ Ð·Ð»Ð¾ÑмÑÑленник не мог ввеÑÑи в поле ÑообÑÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ имени авÑоÑа ÑÑо-нибÑÐ´Ñ Ñакое: | |
− | <SCRIPT>alert(' | + | <SCRIPT>alert('Ðа поÑли Ð²Ñ Ð²Ñе!');</SCRIPT> |
− | + | Ð ÑловÑ, пÑенебÑегаÑÑ Ð¿ÑовеÑкой введеннÑÑ
даннÑÑ
ни в коем ÑлÑÑае нелÑзÑ. ÐайдиÑе как-нибÑÐ´Ñ Ð½Ð° [http://securitylab.ru securitylab.ru] и поÑмоÑÑиÑе, ÑколÑко ÑÑзвимоÑÑей Ñипа «XSS» обнаÑÑживаеÑÑÑ ÐºÐ°Ð¶Ð´Ñй меÑÑÑ! Так ÑÑо ÑÑÑки ÑÑÑками, но поÑледÑÑÐ²Ð¸Ñ Ð¼Ð¾Ð³ÑÑ Ð±ÑÑÑ Ð¾ÑÐµÐ½Ñ ÑеÑÑезнÑми. | |
− | === | + | === ÐÑда же нам ÑепеÑÑ Ð¸Ð´Ñи? === |
− | + | ÐÑак, ÑÑо-Ñо вполне ÑабоÑоÑпоÑобное Ñ Ð½Ð°Ñ ÐµÑÑÑ (Ñм. [[LXF83:Python#img|ÑиÑÑнок]]). Ðо как Ð²Ñ Ð¼Ð¾Ð¶ÐµÑ Ð´Ð¾Ð³Ð°Ð´Ð°ÑÑÑÑ, наÑа гоÑÑÐµÐ²Ð°Ñ Ð¾ÑÐµÐ½Ñ Ð´Ð°Ð»ÐµÐºÐ° Ð¾Ñ ÑовеÑÑенÑÑва. ЧÑо еÑе можно ÑделаÑÑ? ÐÑ, напÑимеÑ, ÑазбиÑÑ Ð½Ð° ÑÑÑаниÑÑ. Ðока ÑообÑений в ней бÑÐ´ÐµÑ Ð½Ðµ болÑÑе дÑжинÑ, ÑÐ¾Ð¹Ð´ÐµÑ Ð¸ Ñак. Ркогда иÑ
ÑиÑло Ð´Ð¾Ð¹Ð´ÐµÑ Ð´Ð¾ ÑоÑни, Ñо Ñедкий полÑзоваÑÐµÐ»Ñ Ð´Ð¾Ð¶Ð´ÐµÑÑÑ Ð¾ÐºÐ¾Ð½ÑÐ°Ð½Ð¸Ñ Ð·Ð°Ð³ÑÑзки вÑеÑ
даннÑÑ
. Ðожно даÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑм возможноÑÑÑ Ð¸ÑполÑзоваÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе HTML-Ñеги, ÑÑÐ¾Ð±Ñ Ð¸Ñ
ÑообÑÐµÐ½Ð¸Ñ Ð²ÑглÑдели более кÑаÑоÑно. Ðожно добавиÑÑ Ñмайликов... Рможно даже ÑделаÑÑ Ð¼Ð¾Ð´ÑÐ»Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑÑиÑованиÑ, позволÑÑÑий ÑедакÑиÑоваÑÑ Ð¸Ð»Ð¸ ÑдалÑÑÑ ÑообÑениÑ, а Ñакже оÑвеÑаÑÑ Ð½Ð° ниÑ
. Так ÑÑо ÑабоÑÑ Ð½ÐµÐ¿Ð¾ÑаÑÑй кÑай. ÐеÑзайÑе â не бÑÐ´Ñ Ð²Ð°Ð¼ меÑаÑÑ. | |
− | === | + | === ÐекоÑоÑÑе ÑаÑпÑоÑÑÑанÑннÑе MIME-ÑÐ¸Ð¿Ñ === |
{| style="background:white;color:black;" border="1" cellspacing="0" | {| style="background:white;color:black;" border="1" cellspacing="0" | ||
|- style="background:#dfcfe6;color:black" | |- style="background:#dfcfe6;color:black" | ||
− | ! MIME- | + | ! MIME-Ñип |
− | ! | + | ! ÐпиÑание |
|- | |- | ||
| text/plain | | text/plain | ||
− | | | + | | ÐÑоÑÑой ÑекÑÑ |
|- | |- | ||
| text/html | | text/html | ||
− | | HTML- | + | | HTML-ÑÑÑаниÑа |
|- | |- | ||
| image/gif | | image/gif | ||
− | | | + | | ÐзобÑажение GIF |
|- | |- | ||
| video/mpeg | | video/mpeg | ||
− | | | + | | Ðидео-Ñайл в ÑоÑмаÑе MPEG |
|- | |- | ||
| application/msword | | application/msword | ||
− | | | + | | ÐокÑÐ¼ÐµÐ½Ñ MS Word |
|} | |} |
Версия 02:00, 22 мая 2009
|
|
|
http://www.textalmoncnad.com Шаблон:Цикл/Python
РабоÑа Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ даннÑÑ Ð¸ web-пÑогÑаммиÑование
ЧаÑÑÑ 3 ЧÑо Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¼Ð¾Ñнее ÑвÑзки «база даннÑÑ + инÑеÑнеÑ»? РеÑли к ÑÑÐ¾Ð¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ ÐµÑе и Python... ЧÑÐ¾Ð±Ñ Ð¿Ð¾ÑÑвÑÑвоваÑÑ Ð²Ñе ÑÑо на пÑакÑике, погÑÑзимÑÑ ÑÐµÐ³Ð¾Ð´Ð½Ñ Ð² пÑÑÐ¸Ð½Ñ SQL-запÑоÑов и HTTP-оÑвеÑов вмеÑÑе Ñ Ð¡ÐµÑгеем СÑпÑÑновÑм.
ÐÑ Ñже видели, ÑÑо Python пÑекÑаÑно Ð¿Ð¾Ð´Ñ Ð¾Ð´Ð¸Ñ Ð´Ð»Ñ ÑабоÑÑ Ñ ÑекÑÑом. Ð ÑÑо Ñакое инÑеÑнеÑ-ÑÑÑаниÑÑ, коÑоÑÑе Ð¼Ð¸Ð»Ð»Ð¸Ð¾Ð½Ñ ÑеÑвеÑов Apache ежедневно миллиаÑдами оÑдаÑÑ Ð½Ð° ÑаÑÑеÑзание наÑим бÑаÑзеÑам? Ðо ÑÑÑи, ÑÐ¾Ñ Ð¶Ðµ ÑекÑÑ, ÑолÑко немножко «гипеÑ»... РзнаÑиÑ, еÑли нам нÑжно бÑÐ´ÐµÑ ÑоÑмиÑоваÑÑ html-ÑÑÑаниÑÑ Ð´Ð¸Ð½Ð°Ð¼Ð¸ÑеÑки, Ñо Python пÑекÑаÑно Ñ ÑÑим ÑпÑавиÑÑÑ. Ð Ð½Ð¸ÐºÐ°ÐºÐ¸Ñ Ð¿ÑепÑÑÑÑвий Ð´Ð»Ñ ÑазÑабоÑки на нем CGI-ÑÑенаÑиев не ÑÑÑеÑÑвÑÐµÑ â web-ÑеÑвеÑÑ, по болÑÑÐ¾Ð¼Ñ ÑÑеÑÑ, безÑазлиÑно, как именно вÑполнÑеÑÑÑ ÑкÑÐ¸Ð¿Ñ Ð¸ на каком ÑзÑке он ÑазÑабоÑан: лиÑÑ Ð±Ñ Ð¾Ð½ Ñмел ÑиÑаÑÑ Ð´Ð°Ð½Ð½Ñе из поÑока ввода и пеÑеменнÑÑ Ð¾ÐºÑÑÐ¶ÐµÐ½Ð¸Ñ Ð´Ð° оÑдаваÑÑ ÑекÑÑ Ð² ÑÑандаÑÑнÑй вÑÑ Ð¾Ð´Ð½Ð¾Ð¹ поÑок.
ÐпÑоÑем, еÑли Ð²Ñ Ð¶Ð°Ð¶Ð´ÐµÑе ÑкоÑоÑÑи, Ñо к ваÑим ÑÑлÑгам mod_Python, да и в Ñежиме FastCGI Python ÑабоÑаÑÑ ÑмееÑ. Ðо ÑейÑÐ°Ñ Ñ Ð½Ð°Ñ ÑÐ°Ð·Ð³Ð¾Ð²Ð¾Ñ Ð²Ñе же не о наÑÑÑÐ¾Ð¹ÐºÐ°Ñ CGI, а о Python, Ñак ÑÑо веÑнемÑÑ Ðº ÑомÑ, Ñади Ñего Ð¼Ñ ÑÑÑ ÑÑаÑÑÑ Ð½Ð°Ñали.
ÐоÑÑановка задаÑи
С лÑбÑм вопÑоÑом лÑÑÑе вÑего ÑазбиÑаÑÑÑÑ Ð½Ð° пÑакÑиÑеÑком пÑимеÑе. ÐоÑÑÐ¾Ð¼Ñ Ð¼Ñ Ð±Ñдем «плÑÑаÑÑ» вокÑÑг неÑложного и, в обÑем-Ñо, доÑÑаÑоÑно баналÑного CGI-пÑиложениÑ: гоÑÑевой книги. Ðаодно ÑазбеÑемÑÑ Ñ Ñем, как Python взаимодейÑÑвÑÐµÑ Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ даннÑÑ , где пÑедÑÑавлÑеÑÑÑ ÑазÑмнÑм Ñ ÑаниÑÑ Ð²Ñе наÑи ÑообÑениÑ.
Ðо пÑежде Ñем пеÑейÑи к ÑаÑÑмоÑÑÐµÐ½Ð¸Ñ ÐºÐ¾Ð´Ð° (Ð²Ñ Ð½Ð°Ð¹Ð´ÐµÑе его Ñеликом на наÑем диÑке), полезно бÑÐ´ÐµÑ Ð´Ð°ÑÑ ÐºÐ¾Ðµ-какÑÑ Ð²Ð²Ð¾Ð´Ð½ÑÑ Ð¸Ð½ÑоÑмаÑиÑ.
УнивеÑÑалÑное «междÑмоÑдÑе» CGI
CGI (Common Gateway Interface, обÑий ÑлÑзовой инÑеÑÑейÑ) бÑл ÑазÑабоÑан как ÑÑедÑÑво взаимодейÑÑÐ²Ð¸Ñ HTTP-ÑеÑвеÑа Ñ Ð¿ÑогÑаммами, коÑоÑÑе могÑÑ Ð·Ð°Ð¿ÑÑкаÑÑÑÑ Ð² опеÑаÑионной ÑиÑÑеме. ÐÑли говоÑиÑÑ ÑпÑоÑенно, Ñо CGI, пеÑÐµÐ´Ð°Ð²Ð°Ñ ÑпÑавление Ñакой пÑогÑамме (обÑÑно Ð¸Ñ Ð¸Ð¼ÐµÐ½ÑÑÑ cgi-ÑÑенаÑиÑми, Ñ Ð¾ÑÑ ÑÑо вполне Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸ двоиÑнÑй Ñайл, ÑазÑабоÑаннÑй на C/C++), ÑоÑмиÑÑÐµÑ Ð´Ð»Ñ Ð½ÐµÐµ опÑеделенное окÑÑжение. Ð ÑаÑÑноÑÑи, паÑамеÑÑÑ HTTP-запÑоÑа, полÑÑенного Ð¾Ñ ÐºÐ»Ð¸ÐµÐ½Ñа, могÑÑ Ð¿Ð¾Ð¼ÐµÑаÑÑÑÑ Ð² опÑеделеннÑе пеÑеменнÑе окÑÑÐ¶ÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ пеÑедаваÑÑÑÑ cgi-пÑогÑамме как аÑгÑменÑÑ Ð¸Ð»Ð¸ как Ð²Ñ Ð¾Ð´Ð½Ð¾Ð¹ поÑок (STDIN). РоÑÐ²ÐµÑ HTTP-ÑеÑÐ²ÐµÑ Ð¶Ð´ÐµÑ Ð´Ð°Ð½Ð½Ñе, коÑоÑÑе cgi-пÑогÑамма должна вÑдаÑÑ Ð² ÑÑандаÑÑнÑй вÑÑ Ð¾Ð´Ð½Ð¾Ð¹ поÑок (STDOUT), и пеÑÐµÐ´Ð°ÐµÑ Ð¸Ñ ÐºÐ»Ð¸ÐµÐ½ÑÑ.
Таким обÑазом, вÑе, ÑÑо ÑÑебÑеÑÑÑ Ð¾Ñ cgi-пÑогÑаммÑ, ÑÑо ÑпоÑобноÑÑÑ Ð¿Ð¾Ð»ÑÑаÑÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼ÑÑ Ð´Ð»Ñ ÑабоÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¸Ð· ÑоÑмиÑÑемой HTTP-ÑеÑвеÑом ÑÑÐµÐ´Ñ Ð¸ возвÑаÑаÑÑ Ð¾ÑвеÑнÑе даннÑе, ÑооÑвеÑÑÑвÑÑÑие пÑоÑÐ¾ÐºÐ¾Ð»Ñ HTTP, ÑÑÐ¾Ð±Ñ web-ÐºÐ»Ð¸ÐµÐ½Ñ Ð·Ð½Ð°Ð», ÑÑо Ñ Ð½Ð¸Ð¼Ð¸ делаÑÑ.
УÑимÑÑ Ð¿Ð¾ÑÑлаÑÑ
ÐаÑнем Ñ ÑоÑмиÑÐ¾Ð²Ð°Ð½Ð¸Ñ HTTP-оÑвеÑа. ЧÑÐ¾Ð±Ñ Ð±ÑаÑÐ·ÐµÑ ÐºÐ»Ð¸ÐµÐ½Ñа мог его пÑавилÑно обÑабоÑаÑÑ, он должен ÑоÑÑоÑÑÑ Ð¸Ð· заголовка и Ñела, ÑазделеннÑÑ Ð¿ÑÑÑой ÑÑÑокой. Рзаголовке пеÑедаеÑÑÑ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð°Ñ ÑлÑÐ¶ÐµÐ±Ð½Ð°Ñ Ð¸Ð½ÑоÑмаÑиÑ, напÑимеÑ, Ñип ÑодеÑжимого, его кодиÑовка, Ñказание бÑаÑзеÑÑ Ð·Ð°Ð¿ÑоÑиÑÑ Ð´ÑÑгой ÑеÑÑÑÑ (Ñак назÑваемое пеÑенапÑавление), и Ñ.д. ÐÑоÑÑейÑий cgi-ÑÑенаÑий на ÑзÑке Python Ð¼Ð¾Ð¶ÐµÑ Ð²ÑглÑдеÑÑ Ñак:
#!/usr/bin/Python # -*- coding: utf-8 -*- print 'Content-Type: text/html\n' print '<H3>ÐÑли Ð²Ñ ÑÑо видиÑе, знаÑÐ¸Ñ Ð²Ñе ÑабоÑаеÑ</H3>'
ÐеÑвÑм опеÑаÑоÑом print Ð¼Ñ ÑоÑмиÑÑем минималÑно Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ñй заголовок â бÑаÑÐ·ÐµÑ ÐºÐ»Ð¸ÐµÐ½Ñа обÑзаÑелÑно должен знаÑÑ, каков Ñип пеÑеÑÑлаемÑÑ ÐµÐ¼Ñ Ð´Ð°Ð½Ð½ÑÑ (в наÑем ÑлÑÑае ÑÑо пÑоÑÑой ÑекÑÑ, ÑооÑвеÑÑÑвÑÑÑий ÑоÑмаÑÑ HTML). Ðе забÑвайÑе о дополниÑелÑном пеÑеводе ÑÑÑоки \n, Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾Ð¼ Ð´Ð»Ñ Ð¾ÑÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° Ð¾Ñ Ñела оÑвеÑа. ÐÑ Ð¸ далее Ð²Ñ Ð¼Ð¾Ð¶ÐµÑе пеÑедаваÑÑ Ð»Ñбой HTML-код.
ÐналогиÑно могÑÑ Ð¿ÐµÑедаваÑÑÑÑ Ð»ÑбÑе обÑекÑÑ, поддеÑживаемÑе клиенÑом: изобÑажениÑ, звÑковÑе ÑайлÑ, css-ÑаблиÑÑ Ð¸ Ñ.д. Ðлавное, ÑÑÐ¾Ð±Ñ Ð·Ð½Ð°Ñение Ð¿Ð¾Ð»Ñ Content-Type (именÑемое Ñакже MIME-Ñипом) ÑооÑвеÑÑÑвовало ÑодеÑжимомÑ.
ÐдеÑÑ Ð¸Ð³ÑаÑÑ, здеÑÑ Ð½Ðµ игÑаÑÑ...
Ðднако какой ÑмÑÑл поÑÑÑаÑÑ ÑоÑмиÑование ÑÑаÑиÑеÑÐºÐ¸Ñ , по ÑÑÑи, ÑÑÑÐ°Ð½Ð¸Ñ cgi-ÑÑенаÑиÑ, еÑли Ñам HTTP-ÑеÑÐ²ÐµÑ ÑпÑавиÑÑÑ Ñ ÑÑим намного лÑÑÑе? РобÑем-Ñо никакого. Разве ÑÑо Ð´Ð»Ñ Ð¾Ð±Ñего ÑазвиÑиÑ... Ð Ð²Ð¾Ñ Ð² Ñем CGI по-наÑÑоÑÑÐµÐ¼Ñ Ñилен, Ñак ÑÑо в ÑоÑмиÑовании динамиÑеÑÐºÐ¸Ñ ÑÑÑаниÑ, ÑодеÑжимое коÑоÑÑÑ Ð·Ð°Ð²Ð¸ÑÐ¸Ñ Ð¾Ñ Ð¸Ð½ÑоÑмаÑии, пеÑеданной полÑзоваÑелем.
ÐÑоÑокол HTTP пÑедÑÑмаÑÑÐ¸Ð²Ð°ÐµÑ Ð½ÐµÑколÑко ÑпоÑобов пеÑедаÑи инÑоÑмаÑии Ð¾Ñ ÐºÐ»Ð¸ÐµÐ½Ñа на ÑеÑвеÑ, назÑваемÑÑ Ð¼ÐµÑодами. Ðаиболее попÑлÑÑнÑе из Ð½Ð¸Ñ â GET, POST, PUT и HEAD.
ÐеÑод GET позволÑÐµÑ Ð²ÑÑавлÑÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð² URL, Ñо еÑÑÑ Ð² ÑÑÑÐ¾ÐºÑ Ð°Ð´ÑеÑа запÑаÑиваемого ÑеÑÑÑÑа. Ðогда «ЯндекÑ» веÑÐ½ÐµÑ Ð²Ð°Ð¼ ÑпиÑок иÑкомÑÑ ÑÑÑаниÑ, поÑмоÑÑиÑе на адÑеÑнÑÑ ÑÑÑÐ¾ÐºÑ Ð² бÑаÑзеÑе â Ð²Ð¾Ñ Ñак даннÑе и пеÑедаÑÑÑÑ Ð¼ÐµÑодом GET. ÐÑÑаÑи, обÑаÑиÑе внимание на Ñо, как вÑе ÑÑо кодиÑÑеÑÑÑ, оÑобенно еÑли Ð²Ñ Ð¸Ñкали какое-Ñо ÑÑÑÑкое Ñлово.
ÐÑли на ÑеÑÐ²ÐµÑ ÑÑебÑеÑÑÑ Ð¿ÐµÑедаÑÑ Ð±Ð¾Ð»ÑÑий обÑем инÑоÑмаÑии, или ее желаÑелÑно ÑкÑÑÑÑ Ð¾Ñ Ð»ÑбопÑÑнÑÑ Ð³Ð»Ð°Ð·, иÑполÑзÑеÑÑÑ Ð´ÑÑгой меÑод â POST. Рданном ÑлÑÑае в заголовке пеÑедаеÑÑÑ Ð»Ð¸ÑÑ ÑÐ°Ð·Ð¼ÐµÑ Ð¿Ð¾Ð»ÑзоваÑелÑÑÐºÐ¸Ñ Ð´Ð°Ð½Ð½ÑÑ , а Ñами даннÑе пеÑеÑÑлаÑÑÑÑ Ð² Ñеле запÑоÑа.
ÐеÑод PUT пÑедназнаÑаеÑÑÑ Ð´Ð»Ñ ÑазмеÑÐµÐ½Ð¸Ñ ÑеÑÑÑÑов на ÑеÑвеÑе и по ÑообÑажениÑм безопаÑноÑÑи пÑакÑиÑеÑки не иÑполÑзÑеÑÑÑ. ÐÑ Ð¸, наконеÑ, меÑод HEAD оÑÐµÐ½Ñ Ð¿Ð¾Ñ Ð¾Ð¶ на GET, за Ñем иÑклÑÑением, ÑÑо ÑеÑÐ²ÐµÑ Ð² оÑÐ²ÐµÑ Ð½Ð° Ñакой запÑÐ¾Ñ Ð²Ð¾Ð·Ð²ÑаÑÐ°ÐµÑ Ð½Ðµ веÑÑ ÑеÑÑÑÑ, а лиÑÑ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¾ нем, ÑакÑÑ ÐºÐ°Ðº даÑа поÑледнего изменениÑ, помеÑаемÑÑ Ð² заголовке. ÐбÑÑно иÑполÑзÑеÑÑÑ Ð¿ÑокÑи-ÑеÑвеÑами Ð´Ð»Ñ Ð¾Ð¿ÑÐµÐ´ÐµÐ»ÐµÐ½Ð¸Ñ Â«ÑвежеÑÑи» имеÑÑÐ¸Ñ ÑÑ Ñ Ð½Ð¸Ñ Ð´Ð°Ð½Ð½ÑÑ â ÑÑÐ¾Ð¸Ñ Ð»Ð¸ запÑаÑиваÑÑ ÑеÑÑÑÑ Ð¿Ð¾Ð²ÑоÑно или можно веÑнÑÑÑ ÐºÐ»Ð¸ÐµÐ½ÑÑ Ñо, ÑÑо еÑÑÑ Ð² кÑÑе.
ÐпÑÐµÐ´ÐµÐ»ÐµÐ½Ð½Ð°Ñ ÑложноÑÑÑ Ð´Ð»Ñ ÑазÑабоÑÑика cgi-ÑÑенаÑÐ¸Ñ Ð·Ð°ÐºÐ»ÑÑаеÑÑÑ Ð² Ñом, ÑÑо даннÑе, оÑпÑавленнÑе ÑазлиÑнÑми меÑодами, пеÑедаÑÑÑÑ Ð² ÑÑенаÑий по-ÑазномÑ. Так, инÑоÑмаÑиÑ, поÑÑÑпивÑÐ°Ñ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ POST, подаеÑÑÑ Ð½Ð° ÑÑандаÑÑнÑй Ð²Ñ Ð¾Ð´ ÑÑенаÑÐ¸Ñ Ð¸ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ ÑÑиÑана оÑÑÑда, напÑимеÑ, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ sys.stdin.read(size) или даже ÑÑнкÑией raw_input() (Ñ Ð¾ÑÑ Ð²Ð¾ вÑоÑом ÑлÑÑае Ñложнее конÑÑолиÑоваÑÑ Ð¾Ð±Ñем пÑинимаемÑÑ Ð´Ð°Ð½Ð½ÑÑ ). ÐолиÑеÑÑво байÑ, коÑоÑÑе ÑÑебÑеÑÑÑ ÑÑиÑаÑÑ, можно полÑÑиÑÑ Ð¸Ð· пеÑеменной окÑÑÐ¶ÐµÐ½Ð¸Ñ CONTENT_LENGTH (напÑимеÑ, Ñак: size = os.environ['CONTENT_LENGTH']).
ÐÑли ÐºÐ»Ð¸ÐµÐ½Ñ Ð¸ÑполÑзÑÐµÑ Ð¼ÐµÑод GET, Ñо даннÑе поÑÑÑпÑÑ Ð² ÑÑенаÑий ÑеÑез пеÑеменнÑÑ ÑÑÐµÐ´Ñ QUERY_STRING. ÐеÑод, коÑоÑÑм даннÑе пеÑÐµÐ´Ð°Ð½Ñ (нÑжно же как-Ñо ÑазобÑаÑÑÑÑ, где Ð¸Ñ Ð¸ÑкаÑÑ) можно вÑегда полÑÑиÑÑ Ð¸Ð· REQUEST_METHOD.
ÐÑÑÑ ÐµÑе один оÑобÑй ÑлÑÑай. ÐÑли даннÑе пеÑедаÑÑÑÑ Ð¼ÐµÑодом GET, но Ñ Ð¸ÑполÑзованием «индекÑного» ÑоÑмаÑа, коÑоÑÑй ÑоÑмиÑÑеÑÑÑ Ñегом <ISINDEX>, Ñо в ÑÑом ÑлÑÑае они кодиÑÑÑÑÑÑ Ð½Ðµ в виде «пеÑеменнаÑ=знаÑение&пеÑеменнаÑ=знаÑение&...», а как «знаÑение+знаÑение+...». Ð cgi-ÑÑенаÑÐ¸Ñ Ð¾Ð½Ð¸ бÑдÑÑ Ð¿ÐµÑеданÑ, помимо QUERY_STRING, ÑеÑез аÑгÑменÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð¾Ð¹ ÑÑÑоки, как еÑли Ð±Ñ ÑÑенаÑий вÑзÑвалÑÑ Ñакой командой:
script.cgi arg1 arg2 arg3
То еÑÑÑ, на ÑÑÐ¾Ñ Ñаз полÑзоваÑелÑÑкие даннÑе можно бÑÐ´ÐµÑ Ð¿Ð¾Ð»ÑÑиÑÑ ÐºÐ°Ðº sys.argv[1] и Ñ.д.
Ðак видиÑе, огÑомное ÑиÑло ваÑианÑов, пÑедÑÑмоÑÑеннÑÑ CGI-инÑеÑÑейÑом, коÑоÑÑе вÑе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ ÑÑÑÐµÐ½Ñ Ð¿Ñи ÑазÑабоÑке ÑÑенаÑиÑ, Ð¼Ð¾Ð¶ÐµÑ Ð²ÑзваÑÑ Ð½ÐµÑвнÑй Ñик даже Ñ Ð¾Ð¿ÑÑнÑÑ Ð¿ÑогÑаммиÑÑов, коÑоÑÑе и во Ñне поÑÐ¸Ñ Ð¾Ð½ÑÐºÑ Ð½Ð°Ð±Ð¸Ð²Ð°ÑÑ Ð¿Ð¾ подÑÑке какой-Ñо код. РеÑли еÑе вÑпомниÑÑ, ÑÑо даннÑе пеÑедаÑÑÑÑ Ð² закодиÑованном виде (ÑÑо англиÑанам Ñ Ð¾ÑоÑо â взÑл знаÑение пеÑеменной и ÑабоÑай, а нам-Ñо Ñ Ð²Ð°Ð¼Ð¸ ÑÑо знаÑение веÑнеÑÑÑ Ð² виде %EC%E4%E0), да еÑе и о пÑовеÑке ÑÑÐ¸Ñ Ð´Ð°Ð½Ð½ÑÑ Ð½Ñжно позабоÑиÑÑÑÑ, ÑÑÐ¾Ð±Ñ ÐºÐ°ÐºÐ¾Ð¹-нибÑÐ´Ñ Ð½Ð°ÑинаÑÑий Ñ Ð°ÐºÐµÑ Ð½Ðµ попÑÑалÑÑ Ð·Ð°ÑÑавиÑÑ Ð½Ð°Ñ ÑеÑÐ²ÐµÑ ÑабоÑаÑÑ Ð¿Ð¾-ÑвоемÑ... ÐеÑ, обо вÑем ÑÑом лÑÑÑе и не вÑпоминаÑÑ. Ðлаго Ñ Ð½Ð°Ñ ÐµÑÑÑ Ð¼Ð¾Ð´ÑÐ»Ñ cgi, в коÑоÑом вÑе ÑÑо Ñже Ñделано!
Ðо о нем â ÑÑÑÑ Ð¿Ð¾Ð·Ð¶Ðµ. СнаÑала паÑÑ Ñлов нÑжно ÑказаÑÑ Ð¾ HTML-ÑоÑÐ¼Ð°Ñ .
ФоÑмиÑÑем ÑоÑмÑ
ЧÑÐ¾Ð±Ñ Ð²Ð°Ð¼ бÑло пÑоÑе понÑÑÑ ÑаÑÑмаÑÑиваемÑй ÑÐµÐ³Ð¾Ð´Ð½Ñ Ð¿ÑимеÑ, коÑоÑко ÑÐºÐ°Ð¶Ñ Ð¿Ñо Ñо, как же ÐºÐ»Ð¸ÐµÐ½Ñ Ð²ÑполнÑÐµÑ Ð¿ÐµÑедаÑÑ Ð´Ð°Ð½Ð½ÑÑ Ð½Ð°ÑÐµÐ¼Ñ cgi-ÑÑенаÑиÑ. ÐонеÑно, пÑодвинÑÑÑе полÑзоваÑели могÑÑ Ð½Ð°Ð±ÑаÑÑ GET-запÑÐ¾Ñ Ð²ÑÑÑнÑÑ Ð² адÑеÑной ÑÑÑоке бÑаÑзеÑа. ХоÑÑ ÑÑо мелоÑиÑÑÑÑ â Ð²ÐµÐ´Ñ Ð¼Ð¾Ð¶Ð½Ð¾ же ÑÑоÑмиÑоваÑÑ Ð¸ POST-запÑоÑ, подклÑÑивÑиÑÑ ÑелнеÑом на 80-й поÑÑ! ÐпÑоÑем, обÑÑнÑе полÑзоваÑели пÑедпоÑиÑаÑÑ Ð±Ð¾Ð»ÐµÐµ понÑÑнÑе и «оÑÑзаемÑе» ÑпоÑобÑ, напÑимеÑ, ÑоÑмÑ.
Ðак они вÑглÑдÑÑ, дÑмаÑ, каждÑй знаеÑ. СоздаÑÑÑÑ Ð¾Ð½Ð¸ Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ñега <FORM>, внÑÑÑи коÑоÑого добавлÑÑÑÑÑ Ñакие ÑлеменÑÑ, как <INPUT> (поле ввода) или <TEXTAREA> (многоÑÑÑоÑнÑй ÑедакÑоÑ). ÐÑим ÑлеменÑам, еÑли Ð¸Ñ Ð´Ð°Ð½Ð½Ñе Ð´Ð¾Ð»Ð¶Ð½Ñ Ð±ÑÑÑ Ð¿ÐµÑÐµÐ´Ð°Ð½Ñ Ð½Ð° ÑеÑвеÑ, пÑиÑваиваÑÑÑÑ Ð¸Ð¼ÐµÐ½Ð° Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð°ÑÑибÑÑа name. ÐаÑалÑное знаÑение задаеÑÑÑ Ð¿Ð°ÑамеÑÑом value и в далÑнейÑем Ð´Ð»Ñ Â«ÑедакÑиÑÑемÑÑ Â» полей Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¾ полÑзоваÑелем. Ðогда полÑзоваÑÐµÐ»Ñ Ð½Ð°Ð¶Ð¸Ð¼Ð°ÐµÑ ÐºÐ½Ð¾Ð¿ÐºÑ Â«ÐÑпÑавиÑÑ» (надпиÑÑ Ð½Ð° ней, в пÑинÑипе, можно измениÑÑ), Ñо бÑаÑÐ·ÐµÑ Ð¾Ð±ÑединÑÐµÑ Ð²Ñе даннÑе полей в паÑÑ name=value, ÑазделÑÑ Ð¸Ñ Ñимволом &. ÐаÑем полÑÑÐµÐ½Ð½Ð°Ñ Ñаким обÑазом ÑÑÑока пеÑедаеÑÑÑ Ð½Ð° ÑеÑÐ²ÐµÑ Ð¼ÐµÑодом, ÑказаннÑм в аÑÑибÑÑе method Ñега <FORM>. ÐÑÑÑ Ðº ÑÑенаÑиÑ, коÑоÑÑй бÑÐ´ÐµÑ Ð·Ð°Ð½Ð¸Ð¼Ð°ÑÑÑÑ ÐµÐµ обÑабоÑкой, задаеÑÑÑ Ð°ÑÑибÑÑом action ÑÑого же Ñега. ÐÑли action не задан, Ñо даннÑе пеÑедаÑÑÑÑ ÑайлÑ, ÑÑоÑмиÑовавÑÐµÐ¼Ñ ÑекÑÑÑÑ ÑÑÑаниÑкÑ.
ÐÑли ÑÑо-Ñо не ÑовÑем понÑÑно, обÑаÑиÑеÑÑ Ðº ÐºÐ¾Ð´Ñ ÑазÑабаÑÑваемой гоÑÑевой книги, коÑоÑÑй пÑиведен ниже.
ÐÐ°Ñ ÑпаÑиÑÐµÐ»Ñ â модÑÐ»Ñ cgi
ÐозвÑаÑаемÑÑ Ðº обÑабоÑке вÑего ÑÑого добÑа, коÑоÑое ÑоÑни полÑзоваÑелей Ñже гоÑÐ¾Ð²Ñ Ð¾Ð±ÑÑÑиÑÑ Ð½Ð° Ð½Ð°Ñ Ð±ÐµÐ´Ð½Ñй ÑÑенаÑий. ÐÑ ÑеÑили воÑполÑзоваÑÑÑÑ ÑÑандаÑÑнÑми ÑÑедÑÑвами Python, и здеÑÑ Ð²Ñе дейÑÑвиÑелÑно оÑÐµÐ½Ñ Ð¿ÑоÑÑо â импоÑÑиÑÑйÑе модÑÐ»Ñ cgi и, Ñоздав обÑÐµÐºÑ ÐºÐ»Ð°ÑÑа FieldStorage, Ð²Ñ Ð¿Ð¾Ð»ÑÑиÑе ÑеÑез него доÑÑÑп ко вÑем даннÑм, пеÑеданнÑм полÑзоваÑелем, незавиÑимо Ð¾Ñ Ð¸ÑполÑзÑемого меÑода:
import cgi data = cgi.FieldStorage() for entry in data.keys(): print 'ÐеÑÐµÐ¼ÐµÐ½Ð½Ð°Ñ %s Ð¸Ð¼ÐµÐµÑ Ð·Ð½Ð°Ñение %s' % (entry, data[entry].value)
ÐÑли вам нÑжно полÑÑиÑÑ Ð·Ð½Ð°Ñение опÑеделенного полÑ, ÑÑо делаеÑÑÑ Ñак:
field = data['field'].value
Ðомимо полÑзоваÑелÑÑÐºÐ¸Ñ Ð´Ð°Ð½Ð½ÑÑ , обÑÐµÐºÑ ÐºÐ»Ð°ÑÑа FieldStorage ÑодеÑÐ¶Ð¸Ñ Ð¸Ð½ÑоÑмаÑÐ¸Ñ Ð¸ о полÑÑ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° (в наÑем пÑимеÑе Ð¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ полÑÑиÑÑ Ð¸Ð· ÑловаÑÑ data.headers). MIME-Ñип даннÑÑ (пеÑедаваемÑй полем заголовка Content-Type) можно полÑÑиÑÑ Ð¸Ð· аÑÑибÑÑа data.type. ЧеÑез ÑÑÐ¾Ñ Ð¶Ðµ обÑÐµÐºÑ Ð¼Ð¾Ð¶ÐµÑ Ð±ÑÑÑ Ð²Ñполнена и загÑÑзка Ñайла.
С помоÑÑÑ Ð¼ÐµÑодов keys() и has_key() можно вÑполнÑÑÑ Ð¾Ð±ÑабоÑÐºÑ Ð¿Ð¾Ð»ÑÑеннÑÑ Ð´Ð°Ð½Ð½ÑÑ Ð² Ñикле и пÑовеÑÑÑÑ Ð½Ð°Ð»Ð¸Ñие Ñой или иной пеÑеменной. ÐÑÑаÑи говоÑÑ, пÑовеÑÑÑÑ Ð½Ð°Ð»Ð¸Ñие пеÑеменной во Ð²Ñ Ð¾Ð´Ð½ÑÑ Ð´Ð°Ð½Ð½ÑÑ , пÑежде Ñем пÑиÑÑÑпаÑÑ Ðº Ð¸Ñ Ð¾Ð±ÑабоÑке, нÑжно непÑеменно â Ð²ÐµÐ´Ñ Ð·Ð°Ð¿ÑÐ¾Ñ ÑоÑмиÑÑеÑÑÑ ÐºÐ»Ð¸ÐµÐ½Ñом, а кÑо знаеÑ, ÑÑо Ñ Ð½ÐµÐ³Ð¾ на Ñме?
ÐазиÑÑем даннÑе
ÐÑак, полÑÑаÑÑ Ð´Ð°Ð½Ð½Ñе Ð¾Ñ ÐºÐ»Ð¸ÐµÐ½Ñа Ð¼Ñ Ð½Ð°ÑÑилиÑÑ. ÐÑпÑавлÑÑÑ Ñоже Ñмеем. ÐÑÑалоÑÑ Ð¿ÑидÑмаÑÑ, как ÑÑи даннÑе лÑÑÑе вÑего Ñ ÑаниÑÑ. ÐонеÑно, Ð´Ð»Ñ Ð½ÐµÑложной гоÑÑевой книги Ñ Ð½ÐµÐ±Ð¾Ð»ÑÑой нагÑÑзкой вполне Ñ Ð²Ð°Ñило Ð±Ñ Ð¸ ÑекÑÑовÑÑ Ñайлов. ÐÑавда, Ñам еÑÑÑ Ñвои ÑложноÑÑи â еÑли ÑÑÐ°Ð·Ñ Ð¿ÑÑÑ Ñеловек Ð·Ð°Ñ Ð¾ÑÑÑ Ð²ÑÑказаÑÑ Ñвое мнение о ваÑей кÑÑÑейÑей домаÑней ÑÑÑаниÑке, Ñо ÑÑенаÑÐ¸Ñ Ð¿ÑидеÑÑÑ ÐºÐ°ÐºÐ¸Ð¼-Ñо обÑазом ÑегÑлиÑоваÑÑ Ð´Ð¾ÑÑÑп к ÑайлÑ-Ñ ÑанилиÑÑ (как минимÑм, обÑабаÑÑваÑÑ ÑиÑÑаÑиÑ, еÑли Ñайл Ñже оÑкÑÑÑ Ð½Ð° запиÑÑ Ð´ÑÑгим ÑкземплÑÑом ÑÑенаÑиÑ). Ðо заÑем нам вÑе ÑÑи головнÑе боли? ÐÑли Ð¼Ñ Ñак ловко оÑвеÑÑелиÑÑ Ð¾Ñ Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи вÑÑÑнÑÑ ÑазбиÑаÑÑ HTTP-запÑоÑÑ, Ñо неÑжели не найдем ÑÑо-Ñо Ð¿Ð¾Ð´Ñ Ð¾Ð´ÑÑее на ÑÑÐ¾Ñ Ñаз?
ÐонеÑно, найдем! Ð ÑÑо «ÑÑо-Ñо» назÑваеÑÑÑ ÑиÑÑемой ÑпÑÐ°Ð²Ð»ÐµÐ½Ð¸Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ даннÑÑ (в пÑоÑÑоÑеÑÑе â СУÐÐ). ТепеÑÑ Ð½Ð°Ñе дело â оÑпÑавиÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð¸ полÑÑиÑÑ Ð¾ÑвеÑ. ÐÑе оÑÑалÑное â Ñже не наÑа забоÑа.
ÐÐ»Ñ ÑÑого пÑимеÑа Ñ Ð²ÑбÑал в каÑеÑÑве «оÑвеÑÑÑвенного» за Ñ Ñанение даннÑÑ ÑеÑÐ²ÐµÑ Ð±Ð°Ð· даннÑÑ PostgreSQL. ÐоÑколÑÐºÑ Ð¼Ñ Ð¿Ð¸Ñем Ð½Ñ Ð¾ÑÐµÐ½Ñ Ð¿ÑоÑÑÑÑ Ð³Ð¾ÑÑевÑÑ ÐºÐ½Ð¸Ð³Ñ, Ñо и ÑÑÑÑкÑÑÑа Ð±Ð°Ð·Ñ Ð±ÑÐ´ÐµÑ Ñ Ð½Ð°Ñ ÑлеменÑаÑной â одна ÑаблиÑа Ñ ÑÑÐµÐ¼Ñ Ð¿Ð¾Ð»Ñми: вÑÐµÐ¼Ñ Ð¿ÑбликаÑии ÑообÑениÑ, Ð¸Ð¼Ñ Ð°Ð²ÑоÑа и, ÑобÑÑвенно, Ñамо ÑообÑение:
admin@toshiba:~$ psql Welcome to psql 8.1.4, the PostgreSQL interactive terminal. guestbook=# create user "www-data" nocreatedb nocreateuser; CREATE ROLE admin=# create database guestbook with owner "www-data"; CREATE DATABASE admin=# \connect guestbook ÐÑ Ð¿Ð¾Ð´ÑоединилиÑÑ Ðº базе даннÑÑ "guestbook". guestbook=# create table guestbook ( guestbook(# datum timestamp, author varchar, message varchar); CREATE TABLE guestbook=# alter table guestbook owner to "www-data"; ALTER TABLE guestbook=# \q admin@toshiba:~$
ÐожалÑй, единÑÑвенное, ÑÑо здеÑÑ Ð½Ñжно поÑÑниÑÑ, ÑÑо поÑÐµÐ¼Ñ Ð±Ð°Ð·Ðµ и ÑаблиÑе Ð¼Ñ Ð½Ð°Ð·Ð½Ð°Ñили владелÑÑем полÑзоваÑÐµÐ»Ñ www-data. ÐÑоÑÑо к ним бÑÐ´ÐµÑ Ð¾Ð±ÑаÑаÑÑÑÑ cgi-ÑÑенаÑий, ÑабоÑаÑÑий Ñ Ð¿Ñавами HTTP-ÑеÑвеÑа Apache, коÑоÑÑй, в ÑÐ²Ð¾Ñ Ð¾ÑеÑедÑ, иÑполнÑеÑÑÑ Ð¾Ñ Ð¸Ð¼ÐµÐ½Ð¸ данного полÑзоваÑÐµÐ»Ñ [в ваÑем диÑÑÑибÑÑиве он Ð¼Ð¾Ð¶ÐµÑ Ð½Ð°Ð·Ð²Ð°ÑÑÑÑ Ð¿Ð¾-дÑÑгомÑ, â пÑим. Ñед.]. Ð PostgreSQL по ÑмолÑÐ°Ð½Ð¸Ñ ÑÑебÑеÑ, ÑÑÐ¾Ð±Ñ Ð¸Ð¼Ñ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð² ÐÐ Ñовпадало Ñ ÐµÐ³Ð¾ ÑиÑÑемнÑм именем. Ðне ÑÑо кажеÑÑÑ Ð´Ð¾ÑÑаÑоÑно ÑдобнÑм, Ñ Ð¾ÑÑ Ð²Ñ, конеÑно, можеÑе поÑÑÑпиÑÑ Ð¿Ð¾-ÑвоемÑ.
DB API на ÑÑÑаже ÑниÑикаÑии
ÐÑÑалоÑÑ ÑазобÑаÑÑÑÑ, как же Python взаимодейÑÑвÑÐµÑ Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ даннÑÑ . ÐÐ»Ñ ÑÑого Python пÑедоÑÑавлÑÐµÑ DB API â ÑпеÑиалÑнÑй инÑеÑÑейÑ, ÑниÑиÑиÑÑÑÑий Ð½Ð°Ð±Ð¾Ñ Ð¼ÐµÑодов, коÑоÑÑе бÑдÑÑ Ð¾Ð´Ð¸Ð½Ð°ÐºÐ¾Ð²Ð¾ ÑабоÑаÑÑ Ð½ÐµÐ·Ð°Ð²Ð¸Ñимо Ð¾Ñ Ñого, Ñ ÐºÐ°ÐºÐ¾Ð¹ СУÐÐ Ð¼Ñ Ð²Ð·Ð°Ð¸Ð¼Ð¾Ð´ÐµÐ¹ÑÑвÑем. ÐÐ»Ñ ÑабоÑÑ Ñ PostgreSQL нам понадобиÑÑÑ Ð¼Ð¾Ð´ÑÐ»Ñ PyPgSQL (в ÑÑандаÑÑной поÑÑавке его Ð¼Ð¾Ð¶ÐµÑ Ð½Ðµ оказаÑÑÑÑ, но Ð²Ð°Ñ Ð¼ÐµÐ½ÐµÐ´Ð¶ÐµÑ Ð¿Ð°ÐºÐµÑов навеÑнÑка бÑÐ´ÐµÑ Ð² кÑÑÑе, как его ÑÑÑановиÑÑ; кÑÑаÑи, ÑÑо не единÑÑвеннÑй модÑÐ»Ñ â Ñ Ð²Ð°Ñ, возможно, бÑÐ´ÐµÑ PyGreSQL, коÑоÑÑй ÑабоÑÐ°ÐµÑ Ð½Ð¸ÑÑÑÑ Ð½Ð¸ Ñ Ñже и Ñ Ñеми же ÑамÑми меÑодами).
DB API опÑеделÑÐµÑ ÑÑандаÑÑнÑе меÑÐ¾Ð´Ñ ÑабоÑÑ Ñ Ð±Ð°Ð·Ð°Ð¼Ð¸ даннÑÑ , Ñак ÑÑо, какой Ð±Ñ Ð¼Ð¾Ð´ÑÐ»Ñ Ð²Ñ Ð½Ð¸ загÑÑзили и Ñ ÐºÐ°ÐºÐ¾Ð¹ Ð±Ñ Ð¡Ð£ÐРни ÑабоÑали (бÑÐ´Ñ Ñо MySQL, PostgreSQL, SQLite или ÑÑо-Ñо еÑе), менÑÑÑÑÑ Ð±ÑÐ´ÐµÑ ÑолÑко Ð¸Ð¼Ñ Ð¼Ð¾Ð´ÑлÑ. Ðлавное, ÑÑÐ¾Ð±Ñ Ð¸ÑполÑзÑемÑй модÑÐ»Ñ ÑооÑвеÑÑÑвовал DB API. РаÑÑмоÑÑим коÑоÑко оÑновнÑе меÑодÑ:
conn = connect(dsn='localhost', user='admin', password='superparol', database='mydb')
Так оÑÑÑеÑÑвлÑеÑÑÑ Ð¿Ð¾Ð´ÐºÐ»ÑÑение к базе. РзавиÑимоÑÑи Ð¾Ñ ÑиÑÑаÑии, вам Ð¼Ð¾Ð¶ÐµÑ Ð¿Ð¾ÑÑебоваÑÑÑÑ ÑказаÑÑ ÑолÑко нÑжнÑе паÑамеÑÑÑ (напÑимеÑ, Ð¸Ð¼Ñ Ñ Ð¾ÑÑа 'localhost' подÑазÑмеваеÑÑÑ Ð¿Ð¾ ÑмолÑаниÑ).
cur = conn.cursor()
ÐÑÑÑоÑÑ Ð¿Ð¾Ð´Ð´ÐµÑживаÑÑÑÑ Ð´Ð°Ð»ÐµÐºÐ¾ не вÑеми СУÐÐ, но Ð´Ð»Ñ Ð¾Ð±ÑноÑÑи в DB API они Ð²Ð²ÐµÐ´ÐµÐ½Ñ Ð¸, в ÑлÑÑае Ð½ÐµÐ¾Ð±Ñ Ð¾Ð´Ð¸Ð¼Ð¾ÑÑи, Ð´Ð¾Ð»Ð¶Ð½Ñ ÑмÑлиÑоваÑÑÑÑ Ð¼Ð¾Ð´ÑлÑми ÑопÑÑÐ¶ÐµÐ½Ð¸Ñ Ð¸ÑкÑÑÑÑвенно. Так ÑÑо не забÑвайÑе оÑпÑавлÑÑÑ Ð²Ñе ваÑи запÑоÑÑ ÑеÑез кÑÑÑоÑ.
cur.execute('''SELECT * FROM mytable''')
Так вÑполнÑеÑÑÑ SQL-запÑоÑ. ÐÑли в ÑÑÑоке запÑоÑа иÑполÑзÑÑÑÑÑ Ð·Ð½Ð°ÐºÐ¾Ð¼ÐµÑÑа %s, Ñо вÑоÑÑм паÑамеÑÑом пеÑедаеÑÑÑ ÑпиÑок пеÑеменнÑÑ -знаÑений, пÑиÑем в SQL-запÑоÑе знакомеÑÑа не ÑÑебÑеÑÑÑ Ð¾ÐºÑÑжаÑÑ Ð°Ð¿Ð¾ÑÑÑоÑами â модÑÐ»Ñ ÑÐ´ÐµÐ»Ð°ÐµÑ ÑÑо ÑамоÑÑоÑÑелÑно в завиÑимоÑÑи Ð¾Ñ Ñипа пеÑеменной.
cur.fetchall()
ÐозвÑаÑÐ°ÐµÑ Ð´Ð²ÑмеÑнÑй ÑпиÑок (ÑÑÑоки â полÑ) полÑÑеннÑÑ Ð¾Ñ Ð¡Ð£ÐРданнÑÑ . СÑÑеÑÑвÑÑÑ Ð¸ дÑÑгие меÑодÑ, ознакомиÑÑÑÑ Ñ ÐºÐ¾ÑоÑÑми Ð²Ñ ÑможеÑе в докÑменÑаÑии или Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ Ð·Ð½Ð°ÐºÐ¾Ð¼Ð¾Ð¹ вам ÑÑнкÑии dir() да паÑÑ-ÑÑойки неÑложнÑÑ ÑкÑпеÑименÑов.
ÐакÑеплÑем на пÑакÑике
ÐеÑейдем к ÑаÑÑмоÑÑÐµÐ½Ð¸Ñ Ð½Ð°Ñего пÑимеÑа. ÐаÑнем ÑÑандаÑÑно â Ñкажем кодиÑовкÑ, подклÑÑим нÑжнÑе модÑли:
#!/usr/bin/Python # -*- coding: utf-8 -*- import PyPgSQL.PgSQL as pg import cgi
Ðалее, опÑеделим две ÑÑнкÑии. ÐеÑÐ²Ð°Ñ Ð±ÑÐ´ÐµÑ Ð¾ÑвеÑаÑÑ Ð·Ð° добавление нового ÑообÑÐµÐ½Ð¸Ñ Ð² базÑ:
def addMessage(author, message): db = pg.connect(database="guestbook") c = db.cursor() c.execute("""INSERT INTO guestbook (datum, author, message) VALUES ('now', %s, %s);""", (author, message)) c.close() db.commit() db.close() print "Content-Type: text/html" print "Location: ?#form\n"
Ðак видиÑе, вÑе оÑÐµÐ½Ñ Ð´Ð°Ð¶Ðµ логиÑно: ÑÑÑанавливаем Ñоединение Ñ ÐÐ (поÑколÑÐºÑ Ð² наÑем ÑлÑÑае подклÑÑение вÑполнÑеÑÑÑ Ñ Ð¸Ð¼ÐµÐ½ÐµÐ¼ ÑекÑÑего ÑиÑÑемного полÑзоваÑелÑ, Ñо доÑÑаÑоÑно ÑказаÑÑ ÑолÑко Ð¸Ð¼Ñ Ð±Ð°Ð·Ñ), Ñоздаем кÑÑÑÐ¾Ñ (в PostgreSQL они не пÑименÑÑÑÑÑ, но они ÑмÑлиÑÑÑÑÑÑ ÐºÐ°Ð¶Ð´Ñм модÑлем, пÑеÑендÑÑÑим на ÑооÑвеÑÑÑвие DB API), вÑполнÑеÑÑÑ Ð·Ð°Ð¿ÑоÑ, закÑÑваеÑÑÑ ÐºÑÑÑоÑ, ÑикÑиÑÑÑÑÑÑ Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ (PostgreSQL иÑполÑзÑÐµÑ ÑÑанзакÑии, поÑÑÐ¾Ð¼Ñ Ð²Ñполнение меÑода commit() обÑзаÑелÑно, инаÑе ваÑи Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð½Ðµ бÑдÑÑ ÑÐ¾Ñ ÑаненÑ), и, наконеÑ, закÑÑваем Ñамо Ñоединение Ñ Ð±Ð°Ð·Ð¾Ð¹. Рполе datum заноÑим знаÑение вÑÑÑоенной пеÑеменной PostgreSQL â now, коÑоÑÐ°Ñ ÐºÐ°Ð¶Ð´Ñй Ñаз заменÑеÑÑÑ ÑекÑÑим знаÑением даÑÑ Ð¸ вÑемени.
ÐÑ Ð¸ пеÑаÑÑ Ð·Ð°Ð³Ð¾Ð»Ð¾Ð²ÐºÐ° «Location» вÑполнÑеÑÑÑ Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ Ð¿ÐµÑенапÑавиÑÑ Ð¿Ð¾Ð»ÑзоваÑÐµÐ»Ñ Ð½Ð° ÑÑÐ¾Ñ Ð¶Ðµ ÑÑенаÑий, но Ñже без паÑамеÑÑов â Ð¼Ñ Ð¶Ðµ Ð´Ð¾Ð»Ð¶Ð½Ñ Ð¿Ð¾ÐºÐ°Ð·Ð°ÑÑ ÐºÐ»Ð¸ÐµÐ½ÑÑ, ÑÑо он на Ñамом деле ввел? (ЯкоÑÑ #form иÑполÑзÑеÑÑÑ, ÑÑÐ¾Ð±Ñ Ð°Ð²ÑомаÑиÑеÑки пÑокÑÑÑиÑÑ ÑÑÑаниÑÐºÑ Ð½Ð° поÑледнее ÑообÑение).
ÐÑоÑÐ°Ñ ÑÑнкÑÐ¸Ñ Ð±ÑÐ´ÐµÑ Ð¾ÑвеÑаÑÑ Ð·Ð° вÑвод на ÑкÑан Ñже оÑÑавленнÑÑ Ð² книге запиÑей, а Ñакже за ÑоÑмÑ, Ñ Ð¿Ð¾Ð¼Ð¾ÑÑÑ ÐºÐ¾ÑоÑой можно бÑÐ´ÐµÑ Ð´Ð¾Ð±Ð°Ð²Ð¸ÑÑ Ð¸ Ñвое вÑÑказÑвание:
def showGB(): db = pg.connect(database="guestbook") c = db.cursor() c.execute("""SELECT datum, author, message FROM guestbook ORDER BY datum;""") res = c.fetchall() c.close() db.close()
Ð ÑÑом ÑÑагменÑе Ð¼Ñ Ð²ÑбиÑаем вÑе ÑÑÑоки из наÑей ÑаблиÑÑ Ð´Ð°Ð½Ð½ÑÑ , ÑоÑÑиÑÑÑ Ð¸Ñ Ð¿Ð¾ даÑе. РезÑлÑÑÐ°Ñ ÑÐ¾Ñ ÑанÑеÑÑÑ Ð² пеÑеменной res, Ñ ÐºÐ¾ÑоÑой и бÑдем ÑабоÑаÑÑ. ТепеÑÑ Ð¾ÑÑалоÑÑ Ð»Ð¸ÑÑ Ð°ÐºÐºÑÑаÑненÑко ÑазложиÑÑ Ð½Ð°Ñи даннÑе по ÑаблиÑкам и вÑвеÑÑи Ð¸Ñ Ð½Ð° ÑкÑан:
print "Content-Type: text/html\n" print "<H1 style='color:#7777FF'><U>ÐелÑкам к нам в гоÑÑи!</U></H1>" for item in res: print """<TABLE width='90%%'> <TR><TD><SMALL>ТоваÑÐ¸Ñ <B>%s</B> поведалнам ÑледÑÑÑее:</SMALL> <TD align='right'><SMALL>%s</SMALL> <TR><TD style='background-color:#DDDDFF' colspan='2'>%s </TABLE>""" % (item[1], str(item[0])[:19], item[2]) print "<HR><A name='form'><H3>ÐÑиÑоединÑйÑеÑÑ Ðº диÑкÑÑÑии:</H3>" print """<FORM method='GET'> ÐаÑе имÑ: <INPUT type='text' name='author'><BR> ЧÑо Ð²Ñ Ð´ÑмаеÑе по ÑÑÐ¾Ð¼Ñ Ð¿Ð¾Ð²Ð¾Ð´Ñ:<BR> <TEXTAREA name='message' rows='5' cols='80'></TEXTAREA><BR> <INPUT type='submit' value='ÐÑпÑавиÑÑ'> </FORM>"""
СмÑÑл конÑÑÑÑкÑии str(item[0])[:19] заклÑÑаеÑÑÑ Ð² Ñом, ÑÑÐ¾Ð±Ñ Ð² ÑÑÑоке вÑемени оÑÑеÑÑ Ð½ÐµÐ½ÑжнÑе нам миллиÑекÑндÑ, коÑоÑÑе ÑÐ¾Ñ ÑанÑÑÑÑÑ Ð² поле Ñипа timestamp. ÐоÑле вÑÐµÑ Ð¾Ð¿ÑбликованнÑÑ ÑообÑений вÑводим ÑоÑÐ¼Ñ Ð´Ð¾Ð±Ð°Ð²Ð»ÐµÐ½Ð¸Ñ Ð½Ð¾Ð²Ð¾Ð³Ð¾, ÑÑÐ¾Ð±Ñ ÐºÐ°Ð¶Ð´Ñй мог пÑиÑоединиÑÑÑÑ Ðº наÑей диÑкÑÑÑии. ÐÑÑаÑи, в Ñеге <FORM> Ð¼Ñ Ð½Ðµ Ñказали паÑамеÑÑ action, поÑколÑÐºÑ Ð´Ð°Ð½Ð½Ñе бÑдÑÑ Ð¿ÐµÑедаваÑÑÑÑ Ð½Ð° обÑабоÑÐºÑ ÑÑÐ¾Ð¼Ñ Ð¶Ðµ ÑÑенаÑÐ¸Ñ (благодаÑÑ ÑÐµÐ¼Ñ Ð¸Ð¼Ñ ÑÑенаÑÐ¸Ñ Ð¼Ð¾Ð¶Ð½Ð¾ пÑиÑвоиÑÑ Ð»Ñбое). ÐаконеÑ, поÑледний ÑÑагменÑ:
form = cgi.FieldStorage() if form.has_key("message") and form.has_key("author"): author = cgi.escape(form["author"].value) message = cgi.escape(form["message"].value) message = message.replace("\n", "<BR>") addMessage(author, message) else: showGB()
Создаем FieldStorage-обÑекÑ, и еÑли в нем еÑÑÑ Ð·Ð°Ð¿Ð¾Ð»Ð½ÐµÐ½Ð½Ñе Ð¿Ð¾Ð»Ñ message и author (Ñо еÑÑÑ Ð·Ð°Ð¿ÑÐ¾Ñ Ð±Ñл ÑÑоÑмиÑован из заполненной полÑзоваÑелем ÑоÑмÑ), Ñо, немножко Ð¸Ñ Ð¾Ð±ÑабоÑав (ÑÑнкÑÐ¸Ñ cgi.escape() заменÑÐµÑ Ð²Ñе «неблагонадежнÑе» ÑÐ¸Ð¼Ð²Ð¾Ð»Ñ â напÑимеÑ, < â Ð¸Ñ ÑÑандаÑÑнÑми SGML-ÑÑÑноÑÑÑми, в данном ÑлÑÑае â <), пеÑедаем ÑÑнкÑии addMessage(). ÐбÑабоÑка нÑжна Ð´Ð»Ñ Ñого, ÑÑÐ¾Ð±Ñ Ð·Ð»Ð¾ÑмÑÑленник не мог ввеÑÑи в поле ÑообÑÐµÐ½Ð¸Ñ Ð¸Ð»Ð¸ имени авÑоÑа ÑÑо-нибÑÐ´Ñ Ñакое:
<SCRIPT>alert('Ðа поÑли Ð²Ñ Ð²Ñе!');</SCRIPT>
Ð ÑловÑ, пÑенебÑегаÑÑ Ð¿ÑовеÑкой введеннÑÑ Ð´Ð°Ð½Ð½ÑÑ Ð½Ð¸ в коем ÑлÑÑае нелÑзÑ. ÐайдиÑе как-нибÑÐ´Ñ Ð½Ð° securitylab.ru и поÑмоÑÑиÑе, ÑколÑко ÑÑзвимоÑÑей Ñипа «XSS» обнаÑÑживаеÑÑÑ ÐºÐ°Ð¶Ð´Ñй меÑÑÑ! Так ÑÑо ÑÑÑки ÑÑÑками, но поÑледÑÑÐ²Ð¸Ñ Ð¼Ð¾Ð³ÑÑ Ð±ÑÑÑ Ð¾ÑÐµÐ½Ñ ÑеÑÑезнÑми.
ÐÑда же нам ÑепеÑÑ Ð¸Ð´Ñи?
ÐÑак, ÑÑо-Ñо вполне ÑабоÑоÑпоÑобное Ñ Ð½Ð°Ñ ÐµÑÑÑ (Ñм. ÑиÑÑнок). Ðо как Ð²Ñ Ð¼Ð¾Ð¶ÐµÑ Ð´Ð¾Ð³Ð°Ð´Ð°ÑÑÑÑ, наÑа гоÑÑÐµÐ²Ð°Ñ Ð¾ÑÐµÐ½Ñ Ð´Ð°Ð»ÐµÐºÐ° Ð¾Ñ ÑовеÑÑенÑÑва. ЧÑо еÑе можно ÑделаÑÑ? ÐÑ, напÑимеÑ, ÑазбиÑÑ Ð½Ð° ÑÑÑаниÑÑ. Ðока ÑообÑений в ней бÑÐ´ÐµÑ Ð½Ðµ болÑÑе дÑжинÑ, ÑÐ¾Ð¹Ð´ÐµÑ Ð¸ Ñак. Ркогда Ð¸Ñ ÑиÑло Ð´Ð¾Ð¹Ð´ÐµÑ Ð´Ð¾ ÑоÑни, Ñо Ñедкий полÑзоваÑÐµÐ»Ñ Ð´Ð¾Ð¶Ð´ÐµÑÑÑ Ð¾ÐºÐ¾Ð½ÑÐ°Ð½Ð¸Ñ Ð·Ð°Ð³ÑÑзки вÑÐµÑ Ð´Ð°Ð½Ð½ÑÑ . Ðожно даÑÑ Ð¿Ð¾Ð»ÑзоваÑелÑм возможноÑÑÑ Ð¸ÑполÑзоваÑÑ Ð½ÐµÐºÐ¾ÑоÑÑе HTML-Ñеги, ÑÑÐ¾Ð±Ñ Ð¸Ñ ÑообÑÐµÐ½Ð¸Ñ Ð²ÑглÑдели более кÑаÑоÑно. Ðожно добавиÑÑ Ñмайликов... Рможно даже ÑделаÑÑ Ð¼Ð¾Ð´ÑÐ»Ñ Ð°Ð´Ð¼Ð¸Ð½Ð¸ÑÑÑиÑованиÑ, позволÑÑÑий ÑедакÑиÑоваÑÑ Ð¸Ð»Ð¸ ÑдалÑÑÑ ÑообÑениÑ, а Ñакже оÑвеÑаÑÑ Ð½Ð° Ð½Ð¸Ñ . Так ÑÑо ÑабоÑÑ Ð½ÐµÐ¿Ð¾ÑаÑÑй кÑай. ÐеÑзайÑе â не бÑÐ´Ñ Ð²Ð°Ð¼ меÑаÑÑ.
ÐекоÑоÑÑе ÑаÑпÑоÑÑÑанÑннÑе MIME-ÑипÑ
MIME-Ñип | ÐпиÑание |
---|---|
text/plain | ÐÑоÑÑой ÑекÑÑ |
text/html | HTML-ÑÑÑаниÑа |
image/gif | ÐзобÑажение GIF |
video/mpeg | Ðидео-Ñайл в ÑоÑмаÑе MPEG |
application/msword | ÐокÑÐ¼ÐµÐ½Ñ MS Word |