Deaktivieren Sie die URL-Manipulation in AngularJS

Lesezeit: 6 Minuten

Deaktivieren Sie die URL Manipulation in AngularJS
Oren

Ich versuche meine erste Web-App mit Angular zu schreiben.

Im normalen Modus (html5Mode aus) erzwingt Angular, dass der Hash-Teil der Adresse wie ein “Pfad” aussieht (ein führendes “https://stackoverflow.com/” hinzugefügt) und Sonderzeichen kodiert – zum Beispiel erlaubt es ein einzelnes “?” und “#” im Hash und ersetzt die anderen durch %3F und %23.

Gibt es eine Möglichkeit diese Funktion auszuschalten? Ich möchte das nicht benutzen $locationProvider / $routeProvider Funktionen – Ich möchte den Hash selbst analysieren (In meinem Fall wird der Benutzer einen “Freitext” in den Hash eingeben, um auf meiner Website zu suchen).

Ich habe gelesen, dass der routeProvider nicht für die Verwendung von regulären Ausdrücken konfiguriert werden kann …

Wenn htmlMode aktiviert ist, muss der Hash-Teil der Adresse nicht wie ein Pfad aussehen (kein führendes “https://stackoverflow.com/”), sondern codiert dennoch Sonderzeichen.

Mir ist bewusst, dass einige Browser die Sonderzeichen sowieso verschlüsseln/escapen, aber wenn der Benutzer einige Sonderzeichen in seine Adressleiste eingegeben hat, möchte ich dies nicht ändern.

Danke

Deaktivieren Sie die URL Manipulation in AngularJS
grae.kindel

Ich bin mir der Nebenwirkungen nicht sicher, aber es erledigt die Arbeit. Beachten Sie, dass alle Standortmanipulationen durch die Winkel-App deaktiviert werden, selbst wenn sie beabsichtigt sind.

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

ES6-Variante:

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

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

Getestet in Chrome 30, IE9, IE10.
Inspiriert von https://stackoverflow.com/a/16678065/369724

  • Danke. Hoffentlich stolpert jemand aus dem anglejs-Team darüber und sagt mir, dass es einen richtigen Weg gibt. Diese Lösung erforderte viel Trial/Error und wurde erst gefunden, als ich anfing, den Quellcode von Angle zu lesen. Der Kunde ist jetzt zufrieden und ich werde den Rahmen verschrotten, sobald ich Zeit habe. Es ist ein beeindruckendes Spielzeug, aber es hat sich als unpraktisch erwiesen, es zu erlernen und zu erweitern.

    – grae.kindel

    7. November ’13 um 2:28

  • Angular versucht erneut, die Position zu manipulieren, was zu einer Endlosschleife führt.

    – gronke

    28. Dez. ’13 um 21:39 Uhr

  • Dieser Code schlägt fehl, wenn Sie ng-include an einer beliebigen Stelle auf der Seite verwenden. Es funktioniert einfach nicht mehr und wirft viele Fehler aus.

    – kazy

    14. Okt ’14 um 11:48

  • Dies scheint ein guter Workaround für anglejs 1.4.3 zu sein. ng-include funktioniert auch.

    – Lestersconyers

    28. September ’15 um 5:03

  • Hat für mich perfekt funktioniert, wenn es eckig mit PJAX im selben Projekt verwendet wurde!

    – Elya Livshitz

    11.11.15 um 4:45


Ich verwende eine lokale Kopie von angle.js. Suchen nach

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

und

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

Kommentieren Sie die entsprechenden Zeilen aus und anglejs stoppt die Überwachung auf Standort-URL-Änderungen.

  • danke, wäre so einfach gewesen, eine Option dafür in anglejs zu machen

    – Elger Mensonides

    13. Juni ’15 um 14:53

1641962349 48 Deaktivieren Sie die URL Manipulation in AngularJS
Drachen

Vielen Dank für die Antwort von @greg.kindel, Sie helfen mir, eine Lösung für das Ankerproblem zu finden. Mit diesem Code kann die AngularJS-App einige Hash-Muster IGNORIEREN, damit sie wie die Browser-Standardeinstellung funktioniert. Ich muss html5Mode nicht aktivieren und ngRoute funktioniert immer noch. 🙂

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;
    }]);
}]);

Getestet in Chrome 69, Firefox 62

AngularJS 1.7.4

  • Hallo Dragon, können Sie diese Antwort bitte anpassen, um Ruheparameter zu verwenden? EsLint beschwert sich ansonsten über den obigen Code.

    – Naomi

    23. September ’19 um 16:05 Uhr

  • @Naomi Fertig. (bevorzuge-ruhe-params)

    – Drachen

    24. September 19 um 10:11

Der Workaround von @greg.kindel (die akzeptierte Lösung) hat bei mir nicht funktioniert. Es warf viele Fehler über eine Endlosschleife. Ich verwende Angular 1.5.8.

Ich konnte diese Problemumgehung wie folgt anpassen, damit die Dinge funktionieren. Ich hoffe, es erspart anderen den Kummer.

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;
    }]);
  }])

Wenn ich mich richtig erinnere, ist das Routing von Angular nicht obligatorisch, aber dann muss man sich um das Nachladen von Controllern, Views usw.

  • Es ist nicht obligatorisch, aber es ist immer eingeschaltet. Sie sehen dies, wenn Sie eine Seite haben (foo.html#abc). Wenn Sie es neu laden, wird es (foo.html#/abc). Der Konflikt, den ich hatte, war, dass die window.history API fehlschlug, wenn pushState(…);back();forward(); weil angle die URL ersetzte, so dass der Weiterleitungsverlauf verloren ging – obwohl ich im anglejs-Teil der Seite überhaupt kein Routing verwendet habe.

    – grae.kindel

    7. November ’13 um 2:22

  • Ich würde einen benutzerdefinierten Angular-Build ausprobieren, obwohl ich das selbst noch nie gemacht habe 🙂 Der Teufel steckt in der src/ng/location.js. Der Verweis auf diese Datei sollte entfernt werden aus angularFiles.js damit Grunt es nicht verpackt. Ich nehme an, Sie sollten auch den Verweis auf entfernen $LocationProvider von src/AngularPublic.js um Fehler zu vermeiden.

    – Adam

    13. November ’13 um 23:29

  • Es ist nicht obligatorisch, aber es ist immer eingeschaltet. Sie sehen dies, wenn Sie eine Seite haben (foo.html#abc). Wenn Sie es neu laden, wird es (foo.html#/abc). Der Konflikt, den ich hatte, war, dass die window.history API fehlschlug, wenn pushState(…);back();forward(); weil angle die URL ersetzte, so dass der Weiterleitungsverlauf verloren ging – obwohl ich im anglejs-Teil der Seite überhaupt kein Routing verwendet habe.

    – grae.kindel

    7. November ’13 um 2:22

  • Ich würde einen benutzerdefinierten Angular-Build ausprobieren, obwohl ich das selbst noch nie gemacht habe 🙂 Der Teufel steckt in der src/ng/location.js. Der Verweis auf diese Datei sollte entfernt werden aus angularFiles.js damit Grunt es nicht verpackt. Ich nehme an, Sie sollten auch den Verweis auf entfernen $LocationProvider von src/AngularPublic.js um Fehler zu vermeiden.

    – Adam

    13. November ’13 um 23:29

.

417510cookie-checkDeaktivieren Sie die URL-Manipulation in AngularJS

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy