【问题标题】:I want to get the backend url from frontend without using hardcoded URLs yii2我想从前端获取后端 url,而不使用硬编码的 URL yii2
【发布时间】:2019-11-19 09:49:08
【问题描述】:
'urlManagerBackend' => [
        'class' => 'yii\web\urlManager',
        'baseUrl' =>  'http://backend.test',
        'enablePrettyUrl' => true,
        'showScriptName' => true,
    ],

然后我想显示保存在uploads目录下的图片

<img src="<?= Yii::$app->urlManagerBackend->baseUrl; ?>/uploads/logo.jpg>

问题是这个网址不能像这样硬编码:

'baseUrl' =>  'http://backend.test',

【问题讨论】:

  • 你的意思是不能在配置中硬编码?你有不同的环境,基于 env 你可以设置不同的 url。也许你有多个网址?
  • url 'backend.test' 是静态的,项目部署后无法使用
  • 你有办法在前端确定后端域吗?由于指向后端文件夹的域可以是任何东西,因此没有通用的方法来找到它。但是如果你有办法确定域(例如你知道后端域将是backend.frontend-domain.example),你应该可以在应用程序的EVENT_BEFORE_ACTION中设置url管理器的baseUrl。

标签: yii2 yii2-advanced-app yii-components yii2-model yii2-urlmanager


【解决方案1】:

如何动态确定其他应用程序(例如您的前端的后端)的域的唯一方法是解析网络服务器的配置文件

当前应用程序的域(您可以使用Url::base(true) 获得的域)由 Web 服务器设置的请求标头或变量确定。但这些仅适用于当前应用程序,不适用于任何其他应用程序,即使它们是同一项目的一部分。

如果你想解析网络服务器的配置文件,你将不得不面对三大挑战:

  1. 不同的 Web 服务器对配置文件有不同的语法。
  2. 配置文件可能位于任何地方。
  3. 您可能没有读取配置文件的访问权限。

因此,最好尝试考虑一些解决方法,而不是坚持动态确定域。

  1. 制作一个要求后端域的部署脚本。将在生产服务器上部署您的应用程序的人将知道后端应用程序的域,并且可以在部署过程中输入它。然后,部署脚本将在您的配置文件中设置输入的后端域。
  2. 在后端创建一个必须在访问前端应用程序之前访问的页面。您可以在访问后端页面时确定后端的域,然后在前端配置文件中设置该域。如果在设置后端域之前访问前端,则只会显示必须先访问后端页面的通知。

【讨论】:

    【解决方案2】:

    在 config 文件夹中应该有一个名为 params.php 的文件。如果你有这样的事情

    <?php
    
    return [
        'adminEmail' => 'admin@example.com',
        'baseUrl' =>  'http://backend.test',
    ];
    

    你可以像这样在你的代码中使用它

    <img src="<?= Yii::$app->params['baseUrl']; ?>/uploads/logo.jpg>
    

    那么当你搬来住的时候,你只需要编辑params.php文件就行了。

    【讨论】:

    • 这个 url 'backend.test' 是硬编码的,但我不能使用硬编码的 URL。
    • 您将如何确定 URL? @adnenmanssouri @Mike 你为什么使用$this-&gt;redirect,没有那个功能它也应该能正常工作? &lt;img src="&lt;?= Yii::$app-&gt;params['baseUrl'] . '/uploads/logo.jpg'; ?&gt;" /&gt;
    • 糟糕!!!谢谢 Borisa,它被剪切和粘贴得很糟糕!我已经编辑了我的答案。
    • 是的,它不使用 $this->redirect @BorisaEric 我不能使用'backend.test'因为这是一个静态地址,我想要它动态 URL,问题仍然存在现在.我需要帮助
    • Adnen - 我对您对动态的定义感到困惑。我通常的想法是你有 2 个(或更多)URL,比如 backend.test 和 backend.live,每个都有自己的程序文件集。在这种情况下,我提出的方式会起作用。动态 URL 如何为您工作?
    【解决方案3】:

    评论太长,我需要放在这里。

    但我只是想知道在哪种情况下这是有意义的,除非您通过您的应用程序创建 Web 应用程序、站点……,我怀疑您是否这样做。 您知道您的本地域(使用本地环境并放置 url)。 您将知道您的开发域(使用开发环境并放置 url)。 您将知道您的生产域(使用 prod 环境并放置 url)。

    你还可以在 yii2 项目中拥有多个应用程序,例如, 跨 3 个环境的 10 个应用程序,即您将在配置中输入的 30 个 url。

    你能告诉我,如果 url 是动态确定的,你将如何访问你的应用程序 -> 除了 Yii 之外不使用其他任何东西?

    你的步骤是什么?你在浏览器中输入什么?然后我们可以继续。也许我们彼此误解了。

    urlManagerBackend' => [
        'class' => 'yii\web\urlManager',
        'baseUrl' =>  'http://backend.test',
        'enablePrettyUrl' => true,
        'showScriptName' => true,
    ]
    

    如果你想知道你也可以在 Yii2 环境中拥有多个 urlManagerBackend 组件。就像使用参数一样。将其添加到 config.xml 的多个相应位置。因此,在特定环境中,您只需将需要覆盖的键 => 值放在同一文件中。

    【讨论】:

      【解决方案4】:

      您可以简单地为此使用资产和别名:

      如果您有一个 backup/web/uploads/ 文件夹来保存通过后端上传的图像,并且您希望在前端显示这些图像。

      在您的frontend/assets/ 中创建一个新的资产文件,我们称之为BackendAsset.php

      <?php
      
         namespace frontend\assets;
         use yii\web\AssetBundle;
      
         class BackendAsset extends AssetBundle {
            public $sourcePath = '@backend/web/uploads';
         }
      

      $sourcePath 是您希望在前端访问的后端文件夹(源)。 @backend 别名是 predefined in the advanced template,所以我们将使用它。

      现在在我们看来,我们可以简单地使用 BackendAsset:

      <?php
      
          use frontend\assets\BackendAsset;
          $backend = BackendAsset::register($this);
      
      ?>
      

      现在我们可以轻松地显示一个文件,比如说backend/web/uploads/somefile.jpg

      <img src="<?= $backend->baseUrl . '/somefile.jpg' ?>" >
      

      注意:以这种方式使用资产将所有文件backend/web/uploads 复制到前端的资产文件夹中。为了防止这种情况,您可以告诉您的应用程序不要复制文件,而是链接到它们(创建 SymLinks),而不是取消linkAssets (yii2 docu):

      在您的应用配置中(在本例中为frontend/config/main.php),将linkAssets 参数设置为TRUE

      'components' => [
          'assetManager' => [
              'linkAssets' => true,
              ]
          ]
      

      【讨论】:

      • 这可以解决资产的问题。但资产并非所有使用 url 管理器的情况。例如,您可能需要创建链接或将用户重定向到后端应用程序。
      • OP 特别提到他想要“显示保存在上传目录下的图像”(从后端,在前端)和“没有硬编码的 URL”——我的建议就是这样做的。将用户重定向到后端应用程序是完全不同的事情(我会使用像 example.com/backend 这样的符号链接来解决)
      • 如果您想将问题限制为显示图像,那么在frontend/web 中创建指向../../backend/web/uploads 的符号链接可能比使用资产更好的解决方案。每次将新文件上传到backend/web/uploads 时,资产的哈希值都会发生变化。这意味着所有图像都将被复制到frontend/web/assets 的新文件夹中,或者新的符号链接将在那里创建,而旧的文件夹/链接将保留在那里。这可能会导致磁盘空间或 inode 数量出现问题。
      【解决方案5】:

      我通过将完整的 url 保存在数据库中来解决这个问题。

      【讨论】:

        【解决方案6】:

        在前端服务器前面放置一个反向代理(例如 nginx)怎么样?
        可以这样配置:

        http://frontend/backend/* -> 将所有内容转发到后端服务,其余的仍将转到前端服务器。

        可以随时更改此反向代理的配置(在本例中为后端服务器的位置)(也可以在部署之后)。

        这可能是一个可行的方案吗?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多