【问题标题】:Give a null response from controller and stop page load - Symfony2从控制器给出空响应并停止页面加载 - Symfony2
【发布时间】:2015-04-01 02:35:39
【问题描述】:

我正在使用 Symfony2,我有一些代码要执行。它执行一些数据库备份类型的工作。这对于这个问题并不重要。

我想要的是当我按下一个按钮时,它会执行代码并返回主视图。不要加载/重新加载任何页面。但控制器总是期待响应。

控制器必须返回一个响应(给定 null)。您是否忘记在控制器的某处添加 return 语句?

所以我试着用null伪造它

按钮代码喜欢

<li id="menu"><a href="{{ path('backup_label') }}"><span class="icon-align-justify"></span> Backup</a></li>

以及我尝试过的响应代码

return $this->render(
        null,
        array('status' => 'ok')

    );

return $this->render(
        '',
        array('status' => 'ok')

    );

return new Response('<html><body></body></html>')

return new Response()

这些要么返回错误,要么返回空白页。

在没有得到新响应的情况下执行一些 php 代码的方法是什么?调用函数,执行并保持相同的视图,无需任何加载,简单。

我可以使用 ajax 来做到这一点。但我希望如果没有 ajax 是可能的。

【问题讨论】:

  • 这没有意义,从逻辑上讲,如果您正在执行某些控制器操作,那么应该有一些响应,因此控制器必须生成一些响应,无论您的请求完成还是失败,都应该检查一下您的要求
  • @MKhalidJunaid 我想要的只是不给页面加载/重新加载。我的代码将下载一个 zip。而已。就是这么简单。但是 symfony 控制器的响应迫使我重新加载/加载。在不加载页面的情况下执行一段代码。并且没有ajax。现在如果应该有回应,我不知道的应该是什么,这就是这个问题的意义。
  • 在官方文档中看这部分:symfony.com/doc/current/components/http_foundation/…。您不需要(尽管可以)手动设置标题 - 您只需要使用适当的响应。
  • @AtanuCSE Alex 是对的,你已经为生成 zip 数据做了你的事情,并以正确的标题返回响应,这样你的页面就不会重新加载,而是从你的控制器下载返回的内容,即压缩文件

标签: php symfony


【解决方案1】:

HTTP 没有“当前”视图的正确概念,因为它是无状态的。这是一个request / response 协议,因此用户对网络服务器的请求的任何操作都必须得到某种响应。

也就是说,出现停留在同一页面上是完全有效的。您可以使用 ajax 或通过发送与用户按下按钮之前相同的内容/响应来响应。你可以使用HTTP_REFERER,但那是not 100% reliable,所以你可能想要使用another method。或者,如果您确定要将用户重定向到哪个页面,只需进行数据库备份并forward 请求正确操作即可。

【讨论】:

  • 我对服务器的请求不需要任何地方重定向,它应该保留在同一页面中。所以是的,我可以产生重定向到同一页面的响应。但这会导致页面重新加载。我想知道我是否可以避免此页面加载?没有ajax? forward 将导致页面重新加载。
  • 这取决于你想做什么。如果您正在触发文件下载,那么您的响应是文件本身,浏览器会将用户保留在当前页面上。如果正在做其他事情,您需要确保客户端的请求不会影响当前响应(页面)。最简单的方法可能是 ajax
【解决方案2】:

尽管如此,下载 zip 文件是一个 HTTP 响应。你可以在 Symfony HTTP 基础中完成你想要做的事情,你也不应该绕过这个标准流程,因为它可能会破坏事情。对于初学者,退出控制器将阻止kernel.terminate 和其他事件触发,因此不会调用侦听器,这可能会破坏您不知道的内容。

改为使用响应对象:

$response = new Response();
$response->headers->set('Content-Description', 'File Transfer');
$response->headers->set('Content-Type', 'application/octet-stream');
$response->headers->set('Content-Disposition', 'attachment; filename=' . basename($zipfname));
$response->setContent(file_get_contents($zipfname));
return $response;

如果您的 zip 文件很大,StreamedResponse 类可能是更好的选择,因为这样它不会将文件内容加载到内存中:

$response = new StreamedResponse(function() use ($zipfname) {
    readfile($zipfname);
});
// set headers
return $response;

【讨论】:

  • 这正是我想要的。我的回答正是现在对我有用的紧急情况。感谢您提供更完美的答案。接受它:)
猜你喜欢
  • 2017-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-22
  • 1970-01-01
  • 2015-04-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多