关闭 AngularJS 中的 URL 操作

IT技术 javascript angularjs address-bar location-provider route-provider
2021-01-29 18:51:57

我正在尝试使用 Angular 编写我的第一个网络应用程序。

在正常模式下(html5Mode 关闭),Angular 强制地址的哈希部分看起来像“路径”(添加前导“/”),并编码特殊字符 - 例如,它允许单个“?” 和散列中的“#”,并用 %3F 和 %23 替换其他的。

有没有办法关闭这个功能?我不想使用$locationProvider / $routeProvider功能 - 我想自己解析散列(在我的情况下,用户将在散列中输入一些“自由文本”以在我的网站内搜索)。

我读到无法将 routeProvider 配置为使用正则表达式...

如果 htmlMode 被打开,那么地址的哈希部分不会被强制看起来像一个路径(没有前导“/”),但它仍然编码特殊字符。

我知道有些浏览器无论如何可能会对特殊字符进行编码/转义,但是如果用户设法在其地址栏中输入了一些特殊字符,那么我不想更改它。

谢谢

5个回答

不确定这样做的副作用,但它可以完成工作。请注意,即使有意,它也会禁用 angular 应用程序的所有位置操作。

angular.module('sample', [])
    .config( ['$provide', function ($provide){
        $provide.decorator('$browser', ['$delegate', function ($delegate) {
            $delegate.onUrlChange = function () {};
            $delegate.url = function () { return ""};
            return $delegate;
        }]);
    }]);

ES6 变体:

angular.module('sample', [])
    .config(["$provide", $provide => {
        $provide.decorator("$browser", ["$delegate", $delegate => {
            $delegate.onUrlChange = () => { };
            $delegate.url = () => "";

            return $delegate;
        }]);
    }]);

在 Chrome 30、IE9、IE10 中测试。
灵感来自https://stackoverflow.com/a/16678065/369724

当您在页面上的任何位置使用 ng-include 时,此代码将失败。它只是停止工作并引发大量错误。
2021-03-23 18:51:57
对于 angularjs 1.4.3,这似乎是一个很好的解决方法。ng-include 也适用。
2021-03-24 18:51:57
Angular 重试操作导致无限循环的位置。
2021-03-25 18:51:57
谢谢。希望 angularjs 团队中的某个人会偶然发现这一点并告诉我有一个正确的方法。这个解决方案进行了大量的试验/错误,直到我开始阅读 angular 的源代码才被发现。客户现在很高兴,我一有时间就废弃这个框架。这是一个令人印象深刻的玩具,但事实证明,学习和扩展是不切实际的。
2021-04-09 18:51:57
在同一个项目中与 PJAX 一起使用 angular 时,对我来说效果很好!
2021-04-13 18:51:57

我使用 angular.js 的本地副本。搜索

$browser.onUrlChange(function(newUrl, newState) {

$rootScope.$watch(function $locationWatch() {

注释掉相应的行,angularjs 将停止监视位置 url 的变化。

谢谢,在 angularjs 中为此做出一个选择会很容易
2021-04-01 18:51:57

感谢@greg.kindel 的回答,你帮我找到了解决锚点问题的方法。这段代码让 AngularJS 应用忽略了一些哈希模式,让它像浏览器默认一样工作。我不需要启用 html5Mode,并且 ngRoute 仍在工作。:)

app.config(['$provide', function ($provide) {
    $provide.decorator('$browser', ['$delegate', '$window', function ($delegate, $window) {
        // normal anchors
        let ignoredPattern = /^#[a-zA-Z0-9].*/;
        let originalOnUrlChange = $delegate.onUrlChange;
        $delegate.onUrlChange = function (...args) {
            if (ignoredPattern.test($window.location.hash)) return;
            originalOnUrlChange.apply($delegate, args);
        };
        let originalUrl = $delegate.url;
        $delegate.url = function (...args) {
            if (ignoredPattern.test($window.location.hash)) return $window.location.href;
            return originalUrl.apply($delegate, args);
        };
        return $delegate;
    }]);
}]);

在 Chrome 69、Firefox 62 中测试

AngularJS 1.7.4

@Naomi 完成。(首选休息参数)
2021-03-16 18:51:57
嗨龙,你能调整这个答案以使用休息参数吗?EsLint 否则会抱怨上述代码。
2021-04-03 18:51:57

@greg.kindel(已接受的解决方案)的解决方法对我不起作用。它抛出了很多关于无限摘要循环的错误。我正在使用 Angular 1.5.8。

我能够将该解决方法调整为以下内容以使事情正常进行。我希望它可以避免其他人的悲伤。

angular.module('sample', [])
  .config(['$provide', function ($provide) {
    $provide.decorator('$browser', ['$delegate', '$window', function ($delegate, $window) {
      $delegate.onUrlChange = function () {};
      //
      // HACK to stop Angular routing from manipulating the URL
      //
      // The url() function seems to get used in two different modes.
      //
      // Mode 1 - Zero arguments
      // There are no arguments given, in which case it appears that the caller is expected the
      // browser's current URL (a string response).
      //
      // Mode 2 - Three arguments
      // It receives three arguments (url, some_boolean, null).  It seems the caller is expecting
      // the browser's URL to be updated to the given value.  The result of this function call is
      // expected to be the $delegate itself, which will subsequently get called with no arguments
      // to check the browser's URL.
      //
      // The Hack:
      // We save the URL so that we can lie to the caller that the URL has been updated to what was
      // requested, but in reality, we'll do nothing to alter the URL.
      //
      var savedUrl = null
      $delegate.url = function (url, ...args) {
        if (!!url) {
          savedUrl = url;
          return $delegate;
        } else {
          return !!savedUrl ? savedUrl : $window.location.href;
        }
      };
      return $delegate;
    }]);
  }])

如果我没记错的话,Angular 的路由不是强制性的,但是您必须注意重新加载控制器、视图等。

我会尝试自定义 Angular 构建,尽管我自己从未这样做过:) 魔鬼在src/ng/location.js. 应该删除对这个文件的引用,这样angularFiles.jsGrunt 就不会打包它。我想您还应该删除对$LocationProviderfrom 的引用src/AngularPublic.js以避免错误。
2021-03-30 18:51:57
这不是强制性的,但它始终处于开启状态。如果您有一个页面 (foo.html#abc),您就会看到这一点。如果重新加载,它会变成 (foo.html#/abc)。我遇到的冲突是在执行 pushState(...);back();forward(); 时 window.history API 失败了。因为 angular 正在替换 url,所以转发历史记录丢失了——即使我在页面的 angularjs 部分根本没有使用路由。
2021-04-03 18:51:57