diff --git a/framework/CHANGELOG.md b/framework/CHANGELOG.md
index e20df1c..263280c 100644
--- a/framework/CHANGELOG.md
+++ b/framework/CHANGELOG.md
@@ -178,6 +178,7 @@ Yii Framework 2 Change Log
 - Chg #4201: change default value of `SyslogTarget::facility` from LOG_SYSLOG to LOG_USER (dizews)
 - Chg #4227: `\yii\widgets\LinkPager::$hideOnSinglePage` is now `true` by default (samdark)
 - Chg #4318: `yii\helpers\Html::ul()` and `ol()` will return an empty list tag if an empty item array is given (qiangxue)
+- Chg #4331: `yii\helpers\Url` now uses `UrlManager` to determine base URL when generating URLs (qiangxue)
 - Chg: Replaced `clearAll()` and `clearAllAssignments()` in `yii\rbac\ManagerInterface` with `removeAll()`, `removeAllRoles()`, `removeAllPermissions()`, `removeAllRules()` and `removeAllAssignments()` (qiangxue)
 - Chg: Added `$user` as the first parameter of `yii\rbac\Rule::execute()` (qiangxue)
 - Chg: `yii\grid\DataColumn::getDataCellValue()` visibility is now `public` to allow accessing the value from a GridView directly (cebe)
diff --git a/framework/helpers/BaseUrl.php b/framework/helpers/BaseUrl.php
index e31c89d..6e4af54 100644
--- a/framework/helpers/BaseUrl.php
+++ b/framework/helpers/BaseUrl.php
@@ -196,13 +196,13 @@ class BaseUrl
             $hasScheme = ($pos = strpos($url, ':')) > 0 && ctype_alpha(substr($url, 0, $pos));
             $char = $url[0];
             if ($char !== '/' && $char !== '#' && $char !== '.' && !$hasScheme) {
-                $url = Yii::$app->getRequest()->getBaseUrl() . '/' . $url;
+                $url = Yii::$app->getUrlManager()->getBaseUrl() . '/' . $url;
             }
         }
 
         if ($scheme) {
             if (empty($hasScheme)) {
-                $url = Yii::$app->getRequest()->getHostInfo() . '/' . ltrim($url, '/');
+                $url = Yii::$app->getUrlManager()->getHostInfo() . '/' . ltrim($url, '/');
             }
             if (is_string($scheme) && ($pos = strpos($url, ':')) !== false) {
                 $url = $scheme . substr($url, $pos);
@@ -223,9 +223,9 @@ class BaseUrl
      */
     public static function base($scheme = false)
     {
-        $url = Yii::$app->getRequest()->getBaseUrl();
+        $url = Yii::$app->getUrlManager()->getBaseUrl();
         if ($scheme) {
-            $url = Yii::$app->getRequest()->getHostInfo() . $url;
+            $url = Yii::$app->getUrlManager()->getHostInfo() . $url;
             if (is_string($scheme) && ($pos = strpos($url, '://')) !== false) {
                 $url = $scheme . substr($url, $pos);
             }
@@ -306,7 +306,7 @@ class BaseUrl
         $url = Yii::$app->getHomeUrl();
 
         if ($scheme) {
-            $url = Yii::$app->getRequest()->getHostInfo() . $url;
+            $url = Yii::$app->getUrlManager()->getHostInfo() . $url;
             if (is_string($scheme) && ($pos = strpos($url, '://')) !== false) {
                 $url = $scheme . substr($url, $pos);
             }
diff --git a/framework/web/UrlManager.php b/framework/web/UrlManager.php
index cebaddb..3aeb23f 100644
--- a/framework/web/UrlManager.php
+++ b/framework/web/UrlManager.php
@@ -125,6 +125,7 @@ class UrlManager extends Component
     public $ruleConfig = ['class' => 'yii\web\UrlRule'];
 
     private $_baseUrl;
+    private $_scriptUrl;
     private $_hostInfo;
 
     /**
@@ -298,7 +299,8 @@ class UrlManager extends Component
 
         $route = trim($params[0], '/');
         unset($params[0]);
-        $baseUrl = $this->getBaseUrl();
+
+        $baseUrl = $this->showScriptName || !$this->enablePrettyUrl ? $this->getScriptUrl() : $this->getBaseUrl();
 
         if ($this->enablePrettyUrl) {
             /* @var $rule UrlRule */
@@ -364,18 +366,18 @@ class UrlManager extends Component
     }
 
     /**
-     * Returns the base URL that is used by [[createUrl()]] to prepend URLs it creates.
-     * It defaults to [[Request::scriptUrl]] if [[showScriptName]] is true or [[enablePrettyUrl]] is false;
-     * otherwise, it defaults to [[Request::baseUrl]].
-     * @return string the base URL that is used by [[createUrl()]] to prepend URLs it creates.
+     * Returns the base URL that is used by [[createUrl()]] to prepend to the URLs it creates.
+     * It defaults to [[Request::baseUrl]].
+     * This is mainly used when [[enablePrettyUrl]] is true and [[showScriptName]] is false.
+     * @return string the base URL that is used by [[createUrl()]] to prepend to the URLs it creates.
      * @throws InvalidConfigException if running in console application and [[baseUrl]] is not configured.
      */
     public function getBaseUrl()
     {
         if ($this->_baseUrl === null) {
             $request = Yii::$app->getRequest();
-            if ($request instanceof \yii\web\Request) {
-                $this->_baseUrl = $this->showScriptName || !$this->enablePrettyUrl ? $request->getScriptUrl() : $request->getBaseUrl();
+            if ($request instanceof Request) {
+                $this->_baseUrl = $request->getBaseUrl();
             } else {
                 throw new InvalidConfigException('Please configure UrlManager::baseUrl correctly as you are running a console application.');
             }
@@ -385,7 +387,8 @@ class UrlManager extends Component
     }
 
     /**
-     * Sets the base URL that is used by [[createUrl()]] to prepend URLs it creates.
+     * Sets the base URL that is used by [[createUrl()]] to prepend to the URLs it creates.
+     * This is mainly used when [[enablePrettyUrl]] is true and [[showScriptName]] is false.
      * @param string $value the base URL that is used by [[createUrl()]] to prepend URLs it creates.
      */
     public function setBaseUrl($value)
@@ -394,6 +397,37 @@ class UrlManager extends Component
     }
 
     /**
+     * Returns the entry script URL that is used by [[createUrl()]] to prepend to the URLs it creates.
+     * It defaults to [[Request::scriptUrl]].
+     * This is mainly used when [[enablePrettyUrl]] is false or [[showScriptName]] is true.
+     * @return string the entry script URL that is used by [[createUrl()]] to prepend to the URLs it creates.
+     * @throws InvalidConfigException if running in console application and [[scriptUrl]] is not configured.
+     */
+    public function getScriptUrl()
+    {
+        if ($this->_scriptUrl === null) {
+            $request = Yii::$app->getRequest();
+            if ($request instanceof Request) {
+                $this->_scriptUrl = $request->getScriptUrl();
+            } else {
+                throw new InvalidConfigException('Please configure UrlManager::scriptUrl correctly as you are running a console application.');
+            }
+        }
+
+        return $this->_scriptUrl;
+    }
+
+    /**
+     * Sets the entry script URL that is used by [[createUrl()]] to prepend to the URLs it creates.
+     * This is mainly used when [[enablePrettyUrl]] is false or [[showScriptName]] is true.
+     * @param string $value the entry script URL that is used by [[createUrl()]] to prepend URLs it creates.
+     */
+    public function setScriptUrl($value)
+    {
+        $this->_scriptUrl = $value;
+    }
+
+    /**
      * Returns the host info that is used by [[createAbsoluteUrl()]] to prepend URLs it creates.
      * @return string the host info (e.g. "http://www.example.com") that is used by [[createAbsoluteUrl()]] to prepend URLs it creates.
      * @throws InvalidConfigException if running in console application and [[hostInfo]] is not configured.
diff --git a/tests/unit/framework/helpers/UrlTest.php b/tests/unit/framework/helpers/UrlTest.php
index c98227e..d7f0ef4 100644
--- a/tests/unit/framework/helpers/UrlTest.php
+++ b/tests/unit/framework/helpers/UrlTest.php
@@ -24,6 +24,12 @@ class UrlTest extends TestCase
                     'hostInfo' => 'http://example.com/',
                     'url' => '/base/index.php&r=site%2Fcurrent&id=42'
                 ],
+                'urlManager' => [
+                    'class' => 'yii\web\UrlManager',
+                    'baseUrl' => '/base',
+                    'scriptUrl' => '/base/index.php',
+                    'hostInfo' => 'http://example.com/',
+                ]
             ],
         ], '\yii\web\Application');
     }
diff --git a/tests/unit/framework/web/UrlManagerTest.php b/tests/unit/framework/web/UrlManagerTest.php
index 8d44e28..70e5ccb 100644
--- a/tests/unit/framework/web/UrlManagerTest.php
+++ b/tests/unit/framework/web/UrlManagerTest.php
@@ -21,6 +21,7 @@ class UrlManagerTest extends TestCase
         // default setting with '/' as base url
         $manager = new UrlManager([
             'baseUrl' => '/',
+            'scriptUrl' => '',
             'cache' => null,
         ]);
         $url = $manager->createUrl(['post/view']);
@@ -31,6 +32,7 @@ class UrlManagerTest extends TestCase
         // default setting with '/test/' as base url
         $manager = new UrlManager([
             'baseUrl' => '/test/',
+            'scriptUrl' => '/test',
             'cache' => null,
         ]);
         $url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
@@ -40,6 +42,7 @@ class UrlManagerTest extends TestCase
         $manager = new UrlManager([
             'enablePrettyUrl' => true,
             'baseUrl' => '/',
+            'scriptUrl' => '',
             'cache' => null,
         ]);
         $url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
@@ -47,13 +50,15 @@ class UrlManagerTest extends TestCase
         $manager = new UrlManager([
             'enablePrettyUrl' => true,
             'baseUrl' => '/test/',
+            'scriptUrl' => '/test',
             'cache' => null,
         ]);
         $url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
         $this->assertEquals('/test/post/view?id=1&title=sample+post', $url);
         $manager = new UrlManager([
             'enablePrettyUrl' => true,
-            'baseUrl' => '/test/index.php',
+            'baseUrl' => '/test',
+            'scriptUrl' => '/test/index.php',
             'cache' => null,
         ]);
         $url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
@@ -72,6 +77,7 @@ class UrlManagerTest extends TestCase
                 ],
             ],
             'baseUrl' => '/',
+            'scriptUrl' => '',
         ]);
         $url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
         $this->assertEquals('/post/1/sample+post', $url);
@@ -89,6 +95,7 @@ class UrlManagerTest extends TestCase
                 ],
             ],
             'baseUrl' => '/',
+            'scriptUrl' => '',
             'suffix' => '.html',
         ]);
         $url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post']);
@@ -108,6 +115,7 @@ class UrlManagerTest extends TestCase
                 ],
             ],
             'baseUrl' => '/test',
+            'scriptUrl' => '/test',
         ]);
         $url = $manager->createUrl(['post/view', 'id' => 1, 'title' => 'sample post', 'lang' => 'en']);
         $this->assertEquals('http://en.example.com/test/post/1/sample+post', $url);
@@ -119,6 +127,7 @@ class UrlManagerTest extends TestCase
     {
         $manager = new UrlManager([
             'baseUrl' => '/',
+            'scriptUrl' => '',
             'hostInfo' => 'http://www.example.com',
             'cache' => null,
         ]);