【问题标题】:Symfony - how to serve image from controller with nginx's X-Accel-RedirectSymfony - 如何使用 nginx 的 X-Accel-Redirect 从控制器提供图像
【发布时间】:2017-03-05 23:14:59
【问题描述】:

我只想将受保护的图像提供给授权用户。因此,我在控制器中使用BinaryFileResponse,它工作正常。但是,我想使用 Nginx 的 XSendfile (X-Accel-Redirect)。我已经完成了与 Nginx 的documantation 中解释的相同步骤。

我还添加了BinaryFileResponse::trustXSendfileTypeHeader(); 到控制器。但现在我不断收到 404 响应。

这是我的配置和代码:

Nginx:

server {
    listen 80;
    listen 443 ssl http2;
    server_name symfony.app;
    root "/home/vagrant/Sites/Symfony/web";

    index index.html index.htm index.php app.php app_dev.php;

    charset utf-8;

    location / {
        try_files $uri $uri/ /app.php?$query_string;
    }

    location /images/ {
        internal;
        alias   /home/vagrant/Sites/Symfony/app/media/images/listings/4/;
    }

    client_max_body_size 100m; 

    # DEV
    location ~ ^/(app_dev|app_test|config)\.php(/|$) {
        #fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;  # allows trailing slash after app_dev.php/
        fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
    }

    # PROD
    location ~ ^/app\.php(/|$) {
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/var/run/php/php7.1-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

        fastcgi_intercept_errors off;
        fastcgi_buffer_size 16k;
        fastcgi_buffers 4 16k;
        internal;
    }

    location ~ /\.ht {
        deny all;
    }

    ssl_certificate     /etc/nginx/ssl/symfony.app.crt;
    ssl_certificate_key /etc/nginx/ssl/symfony.app.key;
}

Symfony 控制器:

public function getPictureAction($id)
    {
        $filePath = 'media/images/listings/4/';
        $path = $this->get('kernel')->getRootDir() . '/' . $filePath . $id;

        BinaryFileResponse::trustXSendfileTypeHeader();

        $response = new BinaryFileResponse($path);

        $response->headers->set('Content-Type', 'image/jpg');
        $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE);
        return $response;
    }

所以,转到 http://symfony.app/images/1.jpg 应该返回一个图像,但得到一个 404。

【问题讨论】:

  • 将用于通过getPictureAction获取照片的网址添加到 OP 中
  • @MaxP。你好。我不明白你所说的 OP 是什么意思?
  • OP = 原帖,问题
  • @MaxP。仔细阅读我的帖子,网址在底部

标签: nginx symfony


【解决方案1】:

/images/ 位置被标记为内部,因此来自浏览器的外部请求无法访问它。 http://nginx.org/en/docs/http/ngx_http_core_module.html#internal

我认为getPictureAction 的路由路径是/images/{id},并且它无法访问,因为 nginx 具有相同的位置 /images/ 是内部的并返回 404 错误。

将 nginx 位置重命名为/images-internal/:

location /images-internal/ {
    internal;
    alias   /home/vagrant/Sites/Symfony/app/media/images/listings/4/;
}

并将php代码更改为:

public function getPictureAction(Request $request, $id)
{
    $dir = $this->get('kernel')->getRootDir() . '/' . 'media/images/listings/4/';
    $path = $dir . $id;

    $request->headers->set('X-Sendfile-Type', 'X-Accel-Redirect');
    $request->headers->set('X-Accel-Mapping', $dir . '=/images-internal/');

    BinaryFileResponse::trustXSendfileTypeHeader();

    $response = new BinaryFileResponse($path);

    $response->headers->set('Content-Type', 'image/jpg');
    $response->setContentDisposition(ResponseHeaderBag::DISPOSITION_INLINE);

    return $response;
}

【讨论】:

  • 成功了。很难看出 nginx 是否直接提供了图像(在标头中找不到任何内容),但是通过调试 BinaryFileResponse 类,我实际上可以看到您的解决方案确实有效。谢谢!
  • 为什么这部分不是 symfony 文档的一部分?
猜你喜欢
  • 2013-04-17
  • 1970-01-01
  • 2015-04-29
  • 1970-01-01
  • 2018-02-02
  • 1970-01-01
  • 2012-10-09
  • 1970-01-01
相关资源
最近更新 更多