perlfaq9
СОДЕРЖАНИЕ
- НАЗВАНИЕ
- ВЕРСИЯ
- ОПИСАНИЕ
- Стоит ли использовать веб-фреймворк?
- Какой веб-фреймворк следует использовать?
- Что такое Plack и PSGI?
- Как удалить HTML из строки?
- Как извлечь URL-адреса?
- Как получить HTML-файл?
- Как автоматизировать отправку HTML-формы?
- Как декодировать или создавать кодировки %-символов в веб-приложениях?
- Как перенаправить на другую страницу?
- Как защитить страницы паролем?
- Как предотвратить ввод данных пользователем, которые могут навредить скрипту CGI?
- Как разобрать заголовок письма?
- Как проверить валидность адреса электронной почты?
- Как декодировать строку MIME/BASE64?
- Как найти адрес электронной почты пользователя?
- Как отправить электронное письмо?
- Как использовать MIME для добавления вложения к сообщению электронной почты?
- Как читать электронную почту?
- Как узнать имя хоста, доменное имя или IP-адрес?
- Как получить/загрузить файл (S)FTP?
- Как реализовать RPC в Perl?
- АВТОР И АВТОРСКИЕ ПРАВА
НАЗВАНИЕ
perlfaq9 - Веб, электронная почта и сети
ВЕРСИЯ
версия 5.20210411
ОПИСАНИЕ
Этот раздел посвящен вопросам, связанным с веб-сайтами, отправкой и получением электронной почты, а также общим вопросам сетевого взаимодействия.
Стоит ли использовать веб-фреймворк?
Да. Если вы создаёте веб-сайт с какой-либо степенью интерактивности (формы/пользователи/базы данных), вам следует использовать фреймворк для упрощения обработки запросов и ответов.
Если интерактивности нет, то вам всё ещё может потребоваться что-то вроде Template Toolkit или Plack::Middleware::TemplateToolkit для облегчения поддержки ваших HTML-файлов (и других ресурсов).
Какой веб-фреймворк следует использовать?
На этот вопрос нет простого ответа. Perl-фреймворки могут поддерживать всё, от простых файловых серверов и небольших интранетов до крупных многонациональных многоязычных веб-сайтов, являющихся основой международных компаний.
Ниже приведен список нескольких фреймворков с комментариями, которые могут помочь вам в принятии решения в зависимости от ваших конкретных требований. Начните с чтения документации, а затем задавайте вопросы на соответствующей почтовой рассылке или в канале IRC.
- Catalyst
-
Сильно ориентированный на объекты и полнофункциональный фреймворк с богатой историей разработки, большим сообществом и экосистемой дополнений. Он отлично подходит для больших и сложных приложений, где вы имеете полный контроль над сервером.
- Dancer2
-
Лишен избыточного наследия, предоставляя легкий и простой в изучении API. Имеет растущую экосистему дополнений. Он лучше всего подходит для небольших проектов и очень прост в освоении для начинающих.
- Mojolicious
-
Самодостаточный и мощный для проектов как малых, так и больших, с упором на HTML5 и технологии реального времени, такие как WebSockets.
- Web::Simple
-
Сильно ориентированный на объекты и минимальный, созданный для скорости и предназначенный как инструментарий для создания микровеб-приложений, пользовательских фреймворков или для связывания существующих совместимых с Plack веб-приложений с одним центральным диспетчером.
Все они взаимодействуют с или используют Plack, понимание основ которого важно при создании веб-сайтов на Perl (много полезных Plack::Middleware).
Что такое Plack и PSGI?
PSGI — это спецификация Perl Web Server Gateway Interface, стандарт, используемый многими Perl-фреймворками. Вам не обязательно понимать его для создания веб-сайта, но вам может пригодиться Plack.
Plack — это набор инструментов для использования стека PSGI. Он содержит компоненты middleware, сервер-ссылку и утилиты для веб-фреймворков. Plack подобен Ruby's Rack или Python's Paste для WSGI.
Вы можете создать веб-сайт с помощью Plack и собственного кода, но для чего-либо, кроме очень простого веб-сайта, использование веб-фреймворка (который использует https://plackperl.org) является лучшим вариантом.
Как удалить HTML из строки?
Используйте HTML::Strip или HTML::FormatText, которое не только удаляет HTML, но и пытается немного отформатировать получившийся простой текст.
Как извлечь URL-адреса?
HTML::SimpleLinkExtor извлечёт URL-адреса из HTML, обрабатывая якоря, изображения, объекты, фреймы и многие другие теги, которые могут содержать URL. Если вам нужно что-то более сложное, вы можете создать свой подкласс HTML::LinkExtor или HTML::Parser. Вы даже можете использовать HTML::SimpleLinkExtor в качестве примера для чего-то, специально подходящего для ваших нужд.
Вы можете использовать URI::Find или URL::Search для извлечения URL из произвольного текстового документа.
Как получить HTML-файл?
(предоставлено brian d foy)
Основной модуль HTTP::Tiny может получать веб-ресурсы и возвращать их содержимое как строку:
use HTTP::Tiny;
my $ua = HTTP::Tiny->new;
my $html = $ua->get( "http://www.example.com/index.html" )->{content}; Он также может сохранить ресурс непосредственно в файл:
$ua->mirror( "http://www.example.com/index.html", "foo.html" ); Если вам нужно выполнить что-то более сложное, объект HTTP::Tiny может быть настроен путём установки атрибутов, или вы можете использовать LWP::UserAgent из дистрибутива libwww-perl или Mojo::UserAgent из дистрибутива Mojolicious, чтобы упростить общие задачи. Если вы хотите смоделировать интерактивный веб-браузер, вы можете использовать модуль WWW::Mechanize.
Как автоматизировать отправку HTML-формы?
Если вы делаете что-то сложное, например, проход по многочисленным страницам и формам или веб-сайту, вы можете использовать WWW::Mechanize. Обратитесь к его документации для получения всех деталей.
Если вы отправляете значения с помощью метода GET, создайте URL и закодируйте форму с помощью метода www_form_urlencode из HTTP::Tiny:
use HTTP::Tiny;
my $ua = HTTP::Tiny->new;
my $query = $ua->www_form_urlencode([ q => 'DB_File', lucky => 1 ]);
my $url = "https://metacpan.org/search?$query";
my $content = $ua->get($url)->{content}; Если вы используете метод POST, метод post_form закодирует содержимое должным образом.
use HTTP::Tiny;
my $ua = HTTP::Tiny->new;
my $url = 'https://metacpan.org/search';
my $form = [ q => 'DB_File', lucky => 1 ];
my $content = $ua->post_form($url, $form)->{content}; Как декодировать или создавать кодировки %-символов в веб-приложениях?
Большинство времени вам не нужно этого делать, так как ваш веб-фреймворк или, если вы делаете запрос, модуль LWP или другой модуль сделают это за вас.
Чтобы закодировать строку самостоятельно, используйте модуль URI::Escape. Функция uri_escape возвращает закодированную строку:
my $original = "Colon : Hash # Percent %";
my $escaped = uri_escape( $original );
print "$escaped\n"; # 'Colon%20%3A%20Hash%20%23%20Percent%20%25' Чтобы декодировать строку, используйте функцию uri_unescape:
my $unescaped = uri_unescape( $escaped );
print $unescaped; # back to original Помните, что не нужно кодировать весь URI целиком, вы должны экранировать каждый компонент отдельно, а затем объединить их.
Как перенаправить на другую страницу?
Большинство Perl-веб-фреймворков имеют механизм для этого, используя фреймворк Catalyst это будет:
$c->res->redirect($url);
$c->detach(); Если вы используете Plack (что делают большинство фреймворков), то Plack::Middleware::Rewrite стоит рассмотреть, если вы мигрируете с Apache или у вас есть URL, которые вы всегда хотите перенаправлять.
Как защитить страницы паролем?
Посмотрите, есть ли в используемом вами веб-фреймворке система аутентификации и подходит ли она вам.
В качестве альтернативы, обратите внимание на Plack::Middleware::Auth::Basic или один из других вариантов аутентификации Plack.
Как предотвратить ввод данных пользователем, которые могут навредить скрипту CGI?
(предоставлено brian d foy)
Вы не можете предотвратить отправку вашему скрипту плохих данных. Даже если вы добавите проверки на стороне клиента, люди могут их отключить или обойти. Например, кто-то может использовать модуль, такой как LWP, для отправки данных на ваш веб-сайт. Если вы хотите предотвратить данные, пытающиеся использовать SQL-инъекции или другие виды атак (и вы должны этого хотеть), вам необходимо не доверять любым данным, вводимым в вашу программу.
Документация perlsec содержит общие советы по безопасности данных. Если вы используете модуль DBI, используйте заглушки для заполнения данных. Если вы запускаете внешние программы с system или exec, используйте списковые формы. Существует множество других мер предосторожности, которые вы должны принять, слишком много, чтобы перечислить их здесь, и большинство из них относятся к категории не использования данных, которые вы не намерены использовать. Не доверяйте никому.
Как разобрать заголовок письма?
Используйте модуль Email::MIME. Он хорошо протестирован и поддерживает всю сложность, которую вы встретите в реальном мире (отступы комментариев, кодировки, комментарии и т. д.).
use Email::MIME;
my $message = Email::MIME->new($rfc2822);
my $subject = $message->header('Subject');
my $from = $message->header('From'); Если у вас уже есть какой-либо другой тип объекта электронной почты, рассмотрите возможность передачи его в Email::Abstract, а затем использование метода cast для получения объекта Email::MIME:
my $abstract = Email::Abstract->new($mail_message_object);
my $email_mime_object = $abstract->cast('Email::MIME'); Как проверить корректность адреса электронной почты?
(частично предоставлено Aaron Sherman)
Это не такой простой вопрос, как кажется. Есть две части:
a) Как проверить, что адрес электронной почты имеет правильный формат?
b) Как проверить, что адрес электронной почты направлен на действительного получателя?
Без отправки письма на адрес и проверки, есть ли человек на другом конце, который вам ответит, вы не можете полностью ответить на часть b, но модуль Email::Valid выполнит и часть a, и часть b, насколько это возможно в реальном времени.
Наш лучший совет по проверке адреса электронной почты человека – попросить его ввести адрес дважды, как обычно делается при смене пароля. Это обычно позволяет избежать опечаток. Если оба варианта совпадают, отправьте письмо на этот адрес с личным сообщением. Если вы получите письмо обратно и человек выполнил ваши инструкции, вы можете быть достаточно уверены, что адрес действителен.
Связанная стратегия, которая менее уязвима для подделки, заключается в предоставлении личного идентификационного номера (PIN). Запишите адрес и PIN (лучше случайный) для последующей обработки. В отправленном письме укажите ссылку на ваш сайт с указанием PIN. Если письмо вернётся как не доставленное, вы знаете, что адрес недействителен. Если они не перейдут по ссылке, либо адрес поддельный, либо (предполагая, что они получили письмо) продолжение действий не было важным, поэтому можете не беспокоиться об этом.
Как декодировать строку MIME/BASE64?
Пакет MIME::Base64 обрабатывает это, а также кодировку MIME/QP. Декодирование Base64 становится таким же простым, как:
use MIME::Base64;
my $decoded = decode_base64($encoded); Модуль Email::MIME может прозрачно декодировать закодированные в Base64 части сообщения электронной почты, так что разработчику не нужно об этом беспокоиться.
Как найти адрес электронной почты пользователя?
Спросите его. Доступно так много поставщиков электронных почт, что локальная система вряд ли сможет определить адрес электронной почты пользователя.
Исключением является электронная почта, специфичная для организации (например, foo@yourcompany.com), где политика может быть кодифицирована в вашей программе. В этом случае можно посмотреть на $ENV{USER}, $ENV{LOGNAME} и получить getpwuid($&) в скалярном контексте, как показано ниже:
my $user_name = getpwuid($<) Но вы по-прежнему не можете делать предположений о правильности этого, если ваша политика этого не требует. Лучше всего спросить пользователя.
Как отправить электронное письмо?
Используйте модуль Email::Stuffer, например так:
# first, create your message
my $message = Email::Stuffer->from('you@example.com')
->to('friend@example.com')
->subject('Happy birthday!')
->text_body("Happy birthday to you!\n");
$message->send_or_die; По умолчанию Email::Sender::Simple (методы send и send_or_die используют это в качестве подпрограммы) попытается использовать sendmail первым, если он существует в вашем $PATH. Это обычно не так. Если у вас есть удалённый почтовый сервер, который вы используете для отправки почты, рассмотрите один из классов транспорта. На момент написания доступны следующие типы транспорта:
- Email::Sender::Transport::Sendmail
-
Это значение по умолчанию. Если вы можете использовать программу mail(1) или mailx(1) для отправки почты с машины, на которой выполняется ваш код, вы можете использовать этот вариант.
- Email::Sender::Transport::SMTP
-
Этот транспорт связывается с удалённым SMTP-сервером по протоколу TCP. Он необязательно использует TLS или SSL и может аутентифицироваться на сервере через SASL.
Указать Email::Stuffer использовать ваш транспорт очень просто.
$message->transport($email_sender_transport_object)->send_or_die; Как использовать MIME для добавления вложений к сообщению электронной почты?
Email::MIME напрямую поддерживает составные сообщения. Объекты Email::MIME сами являются частями и могут быть прикреплены к другим объектам Email::MIME. Обратитесь к документации Email::MIME для получения дополнительной информации, включая все поддерживаемые методы и примеры их использования.
Email::Stuffer использует Email::MIME в качестве внутренней компоненты для построения сообщений и оборачивает наиболее распространённые задачи добавления вложений простыми методами attach и attach_file.
Email::Stuffer->to('friend@example.com')
->subject('The file')
->attach_file('stuff.csv')
->send_or_die; Как читать электронную почту?
Используйте модуль Email::Folder, например так:
use Email::Folder;
my $folder = Email::Folder->new('/path/to/email/folder');
while(my $message = $folder->next_message) {
# next_message returns Email::Simple objects, but we want
# Email::MIME objects as they're more robust
my $mime = Email::MIME->new($message->as_string);
} В пространстве имён Email::Folder есть разные классы для поддержки различных типов почтовых ящиков. Обратите внимание, что эти модули, как правило, довольно ограничены и поддерживают только чтение, а не запись.
Как узнать мой хост-имя, доменное имя или IP-адрес?
(предоставлено brian d foy)
Модуль Net::Domain, который входит в стандартную библиотеку начиная с Perl 5.7.3, может предоставить вам полное доменное имя (FQDN), имя хоста или доменное имя.
use Net::Domain qw(hostname hostfqdn hostdomain);
my $host = hostfqdn(); Модуль Sys::Hostname, являющийся частью стандартной библиотеки, также может предоставить хост-имя:
use Sys::Hostname;
$host = hostname(); Модуль Sys::Hostname::Long использует другой подход и пытается вернуть полное квалифицированное имя хоста:
use Sys::Hostname::Long 'hostname_long';
my $hostname = hostname_long(); Чтобы получить IP-адрес, можно использовать встроенную функцию gethostbyname, чтобы преобразовать имя в число. Чтобы преобразовать это число в формат с точками (a.b.c.d), который ожидают большинство пользователей, используйте функцию inet_ntoa из модуля Socket, который также входит в состав Perl.
use Socket;
my $address = inet_ntoa(
scalar gethostbyname( $host || 'localhost' )
); Как получить/загрузить файл (S)FTP?
Net::FTP и Net::SFTP позволяют взаимодействовать с серверами FTP и SFTP (Secure FTP).
Как реализовать RPC в Perl?
Используйте один из модулей RPC (https://metacpan.org/search?q=RPC).
АВТОР И АВТОРСКИЕ ПРАВА
Авторские права (с) 1997-2010 Tom Christiansen, Nathan Torkington и другие авторы, как указано. Все права защищены.
Данная документация бесплатна; вы можете перераспределять её и/или изменять её на тех же условиях, что и Perl.
Независимо от его распространения, все примеры кода в этом файле объявляются всеобщей собственностью. Вам разрешено и рекомендуется использовать этот код в собственных программах для развлечения или с коммерческой целью по своему усмотрению. Краткий комментарий в коде с указанием авторства будет вежливым жестом, но не является обязательным.
© 1993–2021 Larry Wall and others
Licensed under the GNU General Public License version 1 or later, or the Artistic License.
The Perl logo is a trademark of the Perl Foundation.
https://perldoc.perl.org/5.34.0/perlfaq9