重定向前 Mojo::IOLoop 定时器的问题
Problem with Mojo::IOLoop timer before redirect
我的 Mojolicious 控制器中有一个子程序,它在通过 http post 上传 csv 文件时调用。
上传文件后,会呈现一条消息,显示 "you will be redirected in x seconds"。
所以我想实现 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');
提前致谢
upload
returns 在 Mojo::IOLoop->timer
之后,没有什么等待计时器。您可以尝试使用 Mojo::IOLoop->delay 和 $delay->wait
代替。但我不确定它是如何工作的。所以它可能等同于 sleep
.
你真的需要从 perl 代码重定向吗?您可以使用 setTimeout
渲染一些 js 以获得相同的效果。
事实上,我会建议移动所有文本并重定向到 js 并仅呈现 json,并在 upload
中包含一些状态信息。因此,您可以通过错误处理实现更好的 UI。
redirect_to
实际上是一个 render
,它呈现 HTTP 302 响应以重定向。您不能渲染两次,因此即使您将事务保留到 redirect_to
调用之前,它也已经渲染了页面。因此,您尝试做的事情有两个实际选择;呈现带有 javascript 的页面,它将在超时后执行重定向,或呈现带有元刷新标记的 HTML 页面,这将导致页面在延迟后重定向。 MDN page 讨论了这两种方法。
我的 Mojolicious 控制器中有一个子程序,它在通过 http post 上传 csv 文件时调用。 上传文件后,会呈现一条消息,显示 "you will be redirected in x seconds"。 所以我想实现 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');
提前致谢
upload
returns 在 Mojo::IOLoop->timer
之后,没有什么等待计时器。您可以尝试使用 Mojo::IOLoop->delay 和 $delay->wait
代替。但我不确定它是如何工作的。所以它可能等同于 sleep
.
你真的需要从 perl 代码重定向吗?您可以使用 setTimeout
渲染一些 js 以获得相同的效果。
事实上,我会建议移动所有文本并重定向到 js 并仅呈现 json,并在 upload
中包含一些状态信息。因此,您可以通过错误处理实现更好的 UI。
redirect_to
实际上是一个 render
,它呈现 HTTP 302 响应以重定向。您不能渲染两次,因此即使您将事务保留到 redirect_to
调用之前,它也已经渲染了页面。因此,您尝试做的事情有两个实际选择;呈现带有 javascript 的页面,它将在超时后执行重定向,或呈现带有元刷新标记的 HTML 页面,这将导致页面在延迟后重定向。 MDN page 讨论了这两种方法。