Mojolicious初学(十二)
一、文件上传
文件上传,是一个web框架必不可少的功能之一。我们经常需要收集访问者的一些文件,或者是电子版的一寸照片等情况。
当我们前端web网页请求中包括multipart/form-data头时,Mojolicious框架会依靠Mojo::Upload对象识别param中的上传文件。至于文件的大小,不必担心,超过250KB的文件,Mojolicious会自动缓存到一个临时文件中。
在使用上传文件的过程中,我们可以借助Mojolicious::Plugin::TagHelpers.中的form_for方便的在html模板中快速生成一个上传文件页面:
use Mojolicious::Lite -signatures; # 这是一个上传文件的界面 get '/' => 'form'; # 这里是上传文件的处理过程 post '/upload' => sub ($c) { # 检查上传文件的大小 return $c->render(text => 'File is too big.', status => 200) if $c->req->is_limit_exceeded; # 处理上传的文件 return $c->redirect_to('form') unless my $example = $c->param('example'); my $size = $example->size; my $name = $example->filename; $c->render(text => "Thanks for uploading $size byte file $name."); }; app->start; __DATA__ @@ form.html.ep <!DOCTYPE html> <html> <head><title>Upload</title></head> <body> %= form_for upload => (enctype => 'multipart/form-data') => begin #form_for后跟url,upload是其中一种写法,建议使用"/upload"这种形式更易于理解。 %= file_field 'example' #这里对应后端request param的键名 %= submit_button 'Upload' #‘Upload’代表按钮显示的名称 % end </body> </html>
二、User Agent
这里的User agent不仅仅是html中User agent概念,据我个人研究,Mojolicious中使用Mojo::UserAgent模块更加类似于Perl语言闻名遐迩的爬虫模块LWP::UserAgent。
也就是说,UserAgent在这里代表着内嵌的爬虫结构,可以爬取其他web网页。这种技术,主要的用途在于,api接口,我们可以与其他web系统进行接口集成:
use Mojolicious::Lite -signatures; # 阻塞的、同步的 get '/headers' => sub ($c) { my $url = $c->param('url') || 'https://mojolicious.org'; my $dom = $c->ua->get($url)->result->dom; #爬取'https://mojolicious.org'网页 $c->render(json => $dom->find('h1, h2, h3')->map('text')->to_array); }; # 非阻塞、异步的 get '/title' => sub ($c) { $c->ua->get('mojolicious.org' => sub ($ua, $tx) { $c->render(data => $tx->result->dom->at('title')->text); #同上,异步方式 }); }; # 并发的 get '/titles' => sub ($c) { my $mojo = $c->ua->get_p('https://mojolicious.org'); my $cpan = $c->ua->get_p('https://metacpan.org'); Mojo::Promise->all($mojo, $cpan)->then(sub ($mojo, $cpan) { #协程方式并发爬取两个网站 $c->render(json => { mojo => $mojo->[0]->result->dom->at('title')->text, cpan => $cpan->[0]->result->dom->at('title')->text }); })->wait; }; app->start;