【问题标题】:yii2: how to response image and let browser show it?yii2:如何响应图片并让浏览器显示?
【发布时间】:2015-01-06 13:25:24
【问题描述】:

同样的工作可以通过以下代码完成:

header('Content-Type:image/jpeg');
readfile('a.jpg');

但是现在我真的被 Yii2 的\yii\web\Response.搞糊涂了


我的困惑是这样的:

  1. 创建一个控制器和动作来提供图片

    见下文

    class ServerController extends \yii\web\Controller
    {
        public function actionIndex($name)
        {
            // how to response
        }
    }
    
  2. 访问http://example.com/index.php?r=server/index&name=foo.jpg

感谢您的回答!

【问题讨论】:

  • 请解释您的问题到底是什么

标签: yii2


【解决方案1】:

最后,我通过以下代码做到了:

$response = Yii::$app->getResponse();
$response->headers->set('Content-Type', 'image/jpeg');
$response->format = Response::FORMAT_RAW;
if ( !is_resource($response->stream = fopen($imgFullPath, 'r')) ) {
   throw new \yii\web\ServerErrorHttpException('file access failed: permission deny');
}
return $response->send();

【讨论】:

  • 我已经尝试过您的解决方案。似乎工作!资源不应该以某种方式关闭吗?
  • 我不知道关闭资源连接。如果你已经找到了,能告诉我怎么走吗?
  • 通常应该调用 fclose() 来释放资源。但我认为这是自动完成的(stackoverflow.com/questions/12143343/…)。所以你的解决方案似乎没问题,我猜。
  • 这应该是公认的答案。当我想知道同样的问题时,我正在寻找的事实是 $response->format = Response::FORMAT_RAW.
【解决方案2】:

Yii2 已经内置了sending files 的函数。这样你就不需要设置响应格式并且会自动检测内容类型(如果你愿意,你可以覆盖它):

function actionDownload()
{
    $imgFullPath = 'picture.jpg';
    return Yii::$app->response->sendFile($imgFullPath);
}

..

如果文件只是为当前下载操作临时创建的,您可以使用AFTER_SEND 事件删除文件:

function actionDownload()
{
    $imgFullPath = 'picture.jpg';
    return Yii::$app->response
        ->sendFile($imgFullPath)
        ->on(\yii\web\Response::EVENT_AFTER_SEND, function($event) {
            unlink($event->data);
        }, $imgFullPath);
}

【讨论】:

  • 这应该是可以接受的答案,使用内置的 Yii2 方法!
  • 请记住,这不会为缓存添加标头字段。
【解决方案3】:

在 yii2 中,你可以从 yii\web\Response 类返回一个响应对象。这样您就可以返回自己的响应。

例如在 yii2 中显示图片:

public function actionIndex() {
    \Yii::$app->response->format = yii\web\Response::FORMAT_RAW;
    \Yii::$app->response->headers->add('content-type','image/png');
    \Yii::$app->response->data = file_get_contents('file.png');
    return \Yii::$app->response;
}

FORMAT_RAW:数据将被视为响应内容,无需任何转换。不会添加额外的 HTTP 标头。

【讨论】:

    【解决方案4】:

    我是这样做的。我添加了另一个仅用于设置标题的功能。您也可以在帮助程序中移动此功能:

    $this->setHttpHeaders('csv', 'filename', 'text/plain');
    
    /**
     * Sets the HTTP headers needed by file download action.
     */
    protected function setHttpHeaders($type, $name, $mime, $encoding = 'utf-8')
    {
        Yii::$app->response->format = Response::FORMAT_RAW;
        if (strstr($_SERVER["HTTP_USER_AGENT"], "MSIE") == false) {
            header("Cache-Control: no-cache");
            header("Pragma: no-cache");
        } else {
            header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
            header("Pragma: public");
        }
        header("Expires: Sat, 26 Jul 1979 05:00:00 GMT");
        header("Content-Encoding: {$encoding}");
        header("Content-Type: {$mime}; charset={$encoding}");
        header("Content-Disposition: attachment; filename={$name}.{$type}");
        header("Cache-Control: max-age=0");
    }
    

    我也发现了yii2是怎么做的,看这里(滚动到底部)https://github.com/yiisoft/yii2/blob/48ec791e4aca792435ef1fdce80ee7f6ef365c5c/framework/captcha/CaptchaAction.php

    【讨论】:

      【解决方案5】:

      Yii2 方式:

      Yii::$app->response->setDownloadHeaders($filename);
      

      【讨论】:

      • 感谢您的回答!但看来你没有听懂我的问题。
      猜你喜欢
      • 1970-01-01
      • 2017-12-25
      • 2013-05-20
      • 1970-01-01
      • 2011-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多