web осень 2013 лекция 5
Post on 31-May-2015
434 Views
Preview:
TRANSCRIPT
Серверная разработка
Александр Бекбулатов
2
Что мы научимся делать?
• Обрабатывать GET и POST запросы
• Выводить HTML при помощи шаблонов
• Познакомимся с Django
• Отображение объектов (списки, пагинация,
страницы объектов)
• Изменение объектов (CRUD)
• Взаимодействие с пользователем (формы,
wizard)
Серверная разработка
Типичные задачи серверной разработки
3
Компилируемые:
• С/С++ модули к Web серверам
• Java (Tomcat, Jetty)
• Perl – CGI, mod_perl, PSGI
• PHP – mod_php, FastCGI (FPM)
• Ruby – Rack (mongrel)
• Python – WSGI (Tornado)
• JavaScript (NodeJS)
Языки для серверной разработки
Интерпретируемые:
4
Новая волна?
• Go
• Erlang
• Scala
• Groovy
• …
Языки для серверной разработки
5
#!/usr/bin/python
import osimport sys
print "Content-type: text/html"print "Status: 200"print ""print "<h1>Hello, world!</h1>"
for k, v in os.environ.items(): print "%s = %s<br>" % (k, v)
print >> sys.stderr, "Nice to meet you"
Протокол CGI
6
#!/usr/bin/python print "HTTP/1.0 301 Found"print "Location: http://go.mail.ru/"print "Set-Cookie: name=value"print ""
Протокол CGI
7
HTTP/1.1 200 OK Server: nginx Date: Sun, 27 Oct 2013 10:08:40 GMT Content-Type: text/html; charset=UTF-8 Content-Length: 42510 Connection: keep-alive Cache-Control: private Vary: User-Agent, Accept-Encoding Content-Encoding: gzip X-Recruiting: Like HTTP headers? Come write ours: booking.com/jobs
Заголовки ответа
Booking.com
8
HTTP/1.1 200 OK Content-Type: text/html; charset=UTF-8 Vary: accept-encoding Content-Encoding: gzip Content-Length: 19879 Server: '; DROP TABLE servertypes; -- Date: Sun, 27 Oct 2013 10:10:10 GMT Connection: keep-alive
Заголовки ответа
Reddit.com
9
Гиперссылка
<a href=‘/hello.cgi?name=me&greeting=hello’>Hello!</a>
Переменная окружения
QUERY_STRING=name=me&greeting=hello
CGI скрипт
import urlparse
params = urlparse.parse_qs('name=me&greeting=hello')
GET параметры
10
Форма
<form method=”post” action=”/hello.cgi”>
<input name=”name” value=”me”/>
<input name=”greeting” value=”hi”/>
<input type=”submit”/>
</form>
CGI скрипт
qs = sys.stdin.read()
или
cgi.FieldStorage()
POST параметры
11
multipart/form-data
<form method=”post” action=”/hello.cgi” enctype=”multipart/form-data”>
<input name=”name” value=”me”/>
<input name=”pic” type=”file”/>
<input type=”submit”/>
</form>
URI percent encoding
<a href=”/hello.cgi?name=%D0%B8%D0%BC%D1%8F”>привет</a>
Файлы и не-ASCII
12
import cgiform = cgi.FieldStorage()
# Наличие параметровif not 'name' in form: raise ValidationError('panic')# Валидацияif not re.match('[a-z]+', form['name']): raise ValidationError('panic')# Очисткаstory = re.sub('<[^>]+>', ' ', form['story'])# Экранированиеstory = form['story']story = story.replace('<', '<')story = story.replace('>', '>')
Обработка параметров
13
HTTP_COOKIE
HTTP_USER_AGENT
PATH_INFO
QUERY_STRING
REMOTE_ADDR
REQUEST_METHOD
SCRIPT_FILENAME
SCRIPT_NAME
…
Переменные окружения
14
1. Компилирование программы
2. Другой протокол (FastCGI, SCGI, PCGI, WSGI)
3. Сервлеты в Java
Альтернативы CGI
15
def application(environ, start_response): status = '200 OK' output = 'Hello World!'
response_headers = [ ('Content-type', 'text/plain'), ('Content-Length', str(len(output))) ] start_response(status, response_headers)
return [output]
Протокол WSGI
16
Документация
http://werkzeug.pocoo.org/
Пример приложения
https://github.com/mitsuhiko/werkzeug/blob/master/examples/shortly/shortly.py
Werkzeug
17
from werkzeug.wrappers import Request, Response def application(environ, start_response): request = Request(environ) text = 'Hello %s!' % request.args.get('name', 'World') response = Response(text, mimetype='text/plain') return response(environ, start_response)
Werkzeug
18
from werkzeug.wsgi import DispatcherMiddlewareapp = DispatcherMiddleware(app, { '/app2': app2, '/app3': app3 }) from werkzeug.debug import DebuggedApplication app = DebuggedApplication(app)
Werkzeug Middleware
19
<VirtualHost *> ServerName example.com WSGIScriptAlias /myapp /usr/local/www/wsgi-scripts/myapp.wsgi WSGIDaemonProcess example.com processes=2 threads=15 WSGIProcessGroup example.com <Directory /usr/local/www/wsgi-scripts> Order allow,deny Allow from all </Directory></VirtualHost>
Как запустить?
20
1. UWSGI (C)
2. Tornado (Python)
3. Gunicorn (Python)
Альтернативы
21
Решаемые задачи
22
request = Request(environ)error = Noneurl = ''if request.method == 'POST': url = request.form.get('url') if not is_valid_url(url): error = 'Please enter a valid URL' else: short_id = insert_url(url) return redirect('/%s' % short_id)return render_template('new_url.html', error=error, url=url)
Обработка форм
23
1. Один обработчик для отображения и изменения объекта
2. Сообщение об ошибке и успехе
3. Проверка данных на сервере и клиенте
4. Редирект после выполнения действия
Обработка форм
24
Статусы ответа
301 Moved Permanently302 Found
Куда?
Location: http://go.mail.ru/
Перенаправления
25
var request = $.ajax({url: ”/like/",type: "POST",data: {id : itemId},dataType: "json"
}); request.done(function(result) {
if (result.status) { $("#log").html( result.msg ); }}); request.fail(function(jqXHR, textStatus) {
alert("Request failed: " + textStatus);});
Ajax Frontend
26
Заголовок X-Requested-with для AJAX запросов
import json
request = Request(environ)
json_data = json.dumps({'status': True,
'msg': u'Лайк!'})
response = Response(json_data, mimetype='text/plain')return response(environ, start_response)
Ajax Backend
27
Что нужно хранить о пользователе?
Пользовательские настройки
Временную информацию
Авторизован ли пользователь
Cookie и сессии
Cookie передаются вместе запросом
Сессии хранятся на сервере (в файлах, в базе), идентификатор сессии передаются в куках
Хранение данных на клиенте
28
Cессии
более управляемые (можно сбросить)
снимают ограничение на размер
требуют поддержки бэкенда
могут вызывать проблемы при высоких нагрузках
Cookie
Ограничения на размер и количество
практически не управляемые
передаются по сети с каждым запросом
Cookie и сессии
29
ЗаголовкиSet-Cookie: name=val; path=/; domain=domain.ru; expires=Tue, 20 Mar 2012 11:52:54 GMTCookie: name=val;name2=val2;is_visited=2011-13-15
Установкаimport Cookiecookie = Cookie.SimpleCookie()cookie['name'] = 'val'cookie['name']['path'] = '/path'
Получениеcookie.load('a=b;c=d')for name in cookie: print '%s => %s' % (name, cookie[name])
Cookie
30
'''<html><body>
<h1>%s</h1></body></html>'’’ % name
VS context = { 'user' : get_user(form['name']), 'friends' : get_friends(form['name']) }
render('tpl/home.html', context)
Шаблонизаторы
31
Шаблонизаторы
32
Jinja2 ~ Django
{% extends "layout.html" %}{% block body %} <ul> {% for user in users %} <li> {% include helper %}</li> {% endfor %} </ul>{% endblock %}
Шаблонизаторы
33
<!--# echo var=”Email" default="" -->
<!--# include virtual="/remote/body.php?argument=value" -->
<!--# if expr="$name = /(.+)@(?P<domain>.+)/" -->
<!--# echo var="1" --> <!--# echo var="domain" -->
<!--# endif -->
SSI
34
Фреймворки
35
Готовая архитектура проекта
Экономия ресурсов
Участие в Open Source проектах
Все их используют
Фреймворки
36
Документация
http://flask.pocoo.org/
Примеры приложений
https://github.com/mitsuhiko/flask/tree/master/examples
Flask
37
app = Flask(__name__)
@app.route('/')def index_page(): db = get_db() cur = db.execute('select title, text from entries order by id desc') entries = cur.fetchall() return render_template('show_entries.html', entries=entries)
@app.route('/contact/')def contact_page(): return render_template('contact_page.html')
Flask
38
Model-view-controller – схема использования нескольких шаблонов проектирования, с помощью которых модель данных приложения, пользовательский интерфейс и взаимодействие с пользователем разделены на три отдельных компонента так, что модификация одного из компонентов оказывает минимальное воздействие на остальные.
MVC
39
MVC
40
• PHP (CodeIgniter, Yii)
• ASP (ASP.NET MVC Framework)
• Perl (Catalyst)
• Python (Django, Pyramid)
• Ruby (Ruby on Rails)
Примеры
41
Почему Django
42
Почему Django
43
40+ миллионов пользователей
100+ виртуальных серверов в EC2
Проект куплен Facebook за 1 млрд. долл
1 миллион регистраций за 12 часов после запуска Android-версии
5 разработчиков
Почему Django
44
3 миллиона уникальных посетителей в день
18 миллионов уникальных посетителей в месяц
4-я по популярности социальная сеть в США после Facebook, Twitter и LinkedIn
410Тб пользовательских данных
Почему Django
45
Disqus
500 миллионов уникальных посетителей в месяц
750 тысяч сайтов используют Disqus
1,5 миллиона одновременных пользователей
165 тысяч сообщений в секунду
8 инженеров-разработчиков
Почему Django
46
Другие примеры на http://
www.djangosites.org/
47
Django
48
Возможности
Гибкая ORM
Легко настраиваемый интерфейс администратора
Диспетчер урлов на основе регулярных выражений
Наследование шаблонов
Кеширующий фреймворк
Интернационализация
Шаблоны функций контроллера
Community
Django
49
Приложения
Проект состоит из нескольких приложений
Могут лежать в любом месте PythonPath
Могут использоваться разными проектами
Приложение – раздел сайта либо сквозной функционал
Django
50
Development
python manage.py runserver
Другие полезные возможности
python manage.py help
Deploy
WSGIScriptAlias / /path/to/mysite.com/mysite/wsgi.py
WSGIPythonPath /path/to/mysite.com
Django
51
https://docs.djangoproject.com/
http://django.me/render
https://github.com/django/django
http://www.djangosites.org/with-source/
http://stackoverflow.com/
Полезные ссылки
Спасибо за внимание
Александр Бекбулатов, a.bekbulatov@corp.mail.r
u
top related