我想在不使用硬编码 URL 的情况下从前端获取后端 url yii2

I want to get the backend url from frontend without using hardcoded URLs yii2

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

那我要显示uploads目录下保存的图片

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

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

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

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

<?php

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

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

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

然后搬家的时候,只需要编辑params.php文件即可。

评论太长,所以我需要把它放在这里。

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

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

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

你的步数是多少?你在浏览器里输入什么?然后我们可以继续。也许我们误会了。

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

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

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

如果您有一个 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复制到前端。为防止这种情况,您可以告诉您的应用程序 不要复制 文件,而是 到 link 到它们 (创建 SymLinks),取消 linkAssets (yii2 docu):

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

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

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

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

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

  1. 不同的网络服务器有不同的配置文件语法。
  2. 配置文件可能位于任何位置。
  3. 您可能没有读取配置文件的权限。

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

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

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

在 frontend-server 前面放一个反向代理(例如 nginx)怎么样?
可以这样配置:

http://frontend/backend/* -> 全部转发给后端服务,其余的仍然会转到前端服务器。

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

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