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;

 

 

标签