我的Mojolicious Controller中有一个子程序,当通过http帖子上传csv文件时会调用该子程序。 上传文件后,将显示一条消息,提示您“您将在x秒内被重定向”。 所以我想实现Mojo :: IOLoop :: Delay,作为回调我使用重定向语句。但是我得到了Morbo的以下错误:
Mojo::Reactor::EV: Timer failed: Transaction already destroyed at /usr/local/share/perl/5.22.1/Mojolicious/Plugin/DefaultHelpers.pm line 168.
控制器代码:
sub upload {
my $self = shift;
# Check file size
return $self->render(text => 'File is too big.', status => 200)
if $self->req->is_limit_exceeded;
# Process uploaded file
return $self->redirect_to('/') unless my $newCsv = $self->param('fileToUpload');
my $size = $newCsv->size;
my $name = $newCsv->filename;
my $delay = 2;
$self->render(text => "Thanks for uploading $size byte file $name.<br>
You will be redirected in $delay seconds");
Mojo::IOLoop->timer($delay => sub {
$self->redirect_to('/');
});
}
相关路线:
$r->get('/')->to(controller => 'main', action => 'index');
$r->post('/uploadCsv')->to(controller => 'main', action => 'upload')->name('uploadCsv');
提前谢谢
答案 0 :(得分:2)
redirect_to
实际上是一个render
,它呈现HTTP 302响应以进行重定向。您不能渲染两次,因此即使您在redirect_to
调用之前一直保持事务处理,它也已经渲染了页面。因此,您要尝试执行的操作有两个实际选择:使用超时时间将执行重定向的javascript呈现页面,或使用元刷新标记呈现HTML页面,该HTML页面将在延迟后导致重定向。 MDN page讨论了这两种方法。
答案 1 :(得分:1)
upload
在Mojo::IOLoop->timer
之后返回,没有任何等待计时器。您可以尝试改用Mojo::IOLoop->delay和$delay->wait
。但是我不确定它是如何工作的。因此,它可能只相当于sleep
。
您真的需要从Perl代码重定向吗?您可以使用setTimeout
渲染一些js以达到相同的效果。
实际上,我建议将所有文本移动并重定向到js,并仅在upload
中呈现带有某些状态信息的json。因此,您可以通过错误处理实现更好的UI。