AngularJS: Як очистити параметри запиту в URL?


135

Мій додаток AngularJS повинен мати доступ до профілю LinkedIn користувача. Для цього мені потрібно перенаправити користувача на URL LinkedIn, який містить параметр redirect_uri зворотного виклику, який скаже LinkedIn перенаправити користувача до мого веб-сайту і включить у URL-адресу параметр запиту "код". Це традиційний потік Oauth 2.0.

Все чудово працює, за винятком того, що LinkedIn перенаправляє користувача назад до наступної URL-адреси:

http://localhost:8080/?code=XXX&state=YYY#/users/123/providers/LinkedIn/social-sites

Я хотів би видалити ?code=XXX&state=YYYURL-адресу, щоб зробити її чистою. Користувачеві не потрібно бачити параметри запиту, отримані від переадресації LinkedIn.

Я намагався $location.absUrl($location.path() + $location.hash()).replace(), але він зберігає параметри запиту в URL-адресі.

Я також не можу витягти параметри запиту, наприклад "код", використовуючи ($location.search()).code. Здається, що мати? перед # у вказаній вище URL-адресі відмічається кутовий.

Відповіді:


151

я використовую

$location.search('key', null)

Оскільки це не тільки видаляє мій ключ, але видаляє його із видимості в URL-адресі.


2
це спричиняє цикл кнопок спинки в хромі, оскільки кнопка "назад" повертається до //example.com?key=value, але кутова вперед до //example.com. Пропозиції?
jaybro

2
Це трохи схоже на проблему з кодом. Кутовий не повинен нічого пересилати, якщо тільки ви не додали якийсь король методу. Крім того, додавання .replace () замінює поточний запис історії.
Юлій

viewModelHelper.navigateTo ('foo /'); зберігався рядок запиту до URL-адреси foo, тому я виправив його за допомогою window.location.href = 'foo /'; замість цього.
jaybro

2
Не використовуйте вікно, використовуйте замість нього вікно $ Angular. Простіше буде провести одиничний тест. Більше: docs.angularjs.org/api/ng/service/$window
Юлій

Цей андер працює ідеально, якщо ви хочете видалити спеціальний парам, дякую.
Dexxo

107

Я отримав відповідь з форуму AngularJS. Дивіться цю тему для подробиць


Посилання є на потік груп Google, який важко читати і не дає чіткої відповіді. Для видалення параметрів URL використовуйте

$location.url($location.path());

Я думаю, ви мали намір поставити шлях у $ location.url () замість $ location.path. Спроба об'єднати їх обох, як вище, мені не допомагає.
mbdev

1
не працює і для мене. Обидві функції залишають там парам запиту.
Пабло Езеквієль Леоне

дійсно корисна відповідь. У моєму сценарії кожен раз, коли я вперше запускав $ location.path ('/ reportmaint'). Search ({<myparams>}), він ніколи не очищав попередні параметри запиту.
bob.mazzo

це спричиняє цикл кнопок спинки в хромі, оскільки кнопка "назад" повертається до //example.com?key=value, але кутова вперед до //example.com. Пропозиції?
jaybro

+1 заThe link is to a Google Groups thread, which is difficult to read and doesn't provide a clear answer
Влад

70

Щоб видалити ВСІ параметри запиту, виконайте:

$location.search({});

Щоб видалити ОДИН конкретний параметр запиту, виконайте:

$location.search('myQueryParam', null);

2
Працює і для Angular 1.5.
Manish M Demblani

1
також працює з undefined, якщо ви уникаєте використання такого, nullяк я.
HankScorpio

Що мені не подобається, якщо ви повертаєтесь за допомогою кнопки повернення браузера, ви втрачаєте пошуковий запит, який я раніше робив на попередній сторінці пошуку.
Джино

@Gino Як обхід, ви можете додати запис до історії браузера до цього скидання. stackoverflow.com/q/10541388/586051
Рахул Десай

@RahulDesai Я використовую ng-route, і важко це зробить автоматично
Gino

29

Щоб очистити елемент, видаліть його та зателефонуйте $$ compose

    if ($location.$$search.yourKey) {
        delete $location.$$search.yourKey;
        $location.$$compose();
    }

похідне з angularjs джерела: https://github.com/angular/angular.js/blob/c77b2bcca36cf199478b8fb651972a1f650f646b/src/ng/location.js#L419-L443


2
блискучий! Працював як шарм.
Паульпедперсон

Це працювало для мене, але я вважаю, що рішення Юліуса є більш правильним, оскільки, здається, те, що кутові хлопці мали на увазі під час створення searchметоду. docs.angularjs.org/api/ng/service/$location#search
zmilojko

1
Дякую, це спрацювало непогано ... Цікаво, що IE8 любить встановлювати / складати цю URL-адресу, а потім завантажувати її згодом. Я впевнений, що тому перевагу правильної маршрутизації, а також, чому ми всі погані люди. : P
Романул

27

Ви можете видалити певний параметр запиту, використовуючи:

delete $location.$$search.nameOfParameter;

Або ви можете очистити всі параметри запиту, встановивши пошук на порожній об’єкт:

$location.$$search = {};

2
Я не знаю чому, але це рішення не працює добре під час перемикання сторінок (параметри можуть з’являтися знову, навіть якщо $location.$$search = {}вони виконані). Рішення @basarat працює добре.
Mik378

1
Для мене добре працювало - можливо, перевірити послідовність, в якій ви видаляєте параметр і змінюєте шлях?
деманяк

1
Хоча це може працювати, він отримує доступ до приватних змінних, які не слід змінювати, див. Відповідь на @Julius для іншого рішення
Бен Таліадорос

26

На момент написання, і як раніше згадував @Bosh, html5modeпотрібно мати trueможливість встановити $location.search()та відобразити його назад у візуальній URL-адресі вікна.

Див. Https://github.com/angular/angular.js/isissue/1521 для отримання додаткової інформації.

Але якщо html5mode це,true ви можете легко очистити рядок запиту URL-адреси за допомогою:

$location.search('');

або

$location.search({});

Це також змінить візуальну URL-адресу вікна.

(Випробувано у версії AngularJS 1.3.0-rc.1с html5Mode(true).)


12

Потрібно, щоб це працювало, коли html5mode= false?

Всі інші відповіді працюють тільки тоді , коли Кутова - х html5modeце true. Якщо ви працюєте за межами html5mode, тоді $locationйдеться лише про "підроблене" місце, яке живе у вашому хеші - і тому $location.searchне можна побачити / відредагувати / виправити фактичні параметри пошуку фактичної сторінки.

Ось вирішення, яке потрібно вставити в HTML сторінки перед кутовим завантаженням:

<script>
  if (window.location.search.match("code=")){
    var newHash = "/after-auth" + window.location.search;
    if (window.history.replaceState){
      window.history.replaceState( {}, "", window.location.toString().replace(window.location.search, ""));
    }
    window.location.hash = newHash;
  }
</script>

2
Ще один спосіб я уникав налаштування html5Mode на true, створивши рядок запиту таким чином, щоб він містив # прямо перед ? . так що myapp/#?client=clientName замість цього myapp/?client=clientName
Angel Gao


4

Якщо ви хочете перейти на іншу URL-адресу та очистити параметри запиту, просто скористайтеся:

$location.path('/my/path').search({});

1

Якщо ви використовуєте параметри маршрутів, просто очистіть $ routeParams

$routeParams= null;

1
Це просто встановить локальну змінну $routeParamsна null. Фактично не вплине на параметри URL-адреси в адресному рядку.
Ерік Ф.

1

Як щодо того, щоб просто встановити хеш місця розташування на нуль

$location.hash(null);

0

якщо обробити параметри негайно, а потім перейти на наступну сторінку, ви можете поставити знак питання в кінці нового місця розташування.

наприклад, якби ви зробили $ location.path ('/ nextPage');

ви можете зробити це замість: $ location.path ('/ nextPage?');


0

Я спробував вказані вище відповіді, але не зміг змусити їх працювати. Єдиний код, який працював для мене, був$window.location.search = ''


0

Я можу замінити всі параметри запиту цим єдиним рядком: $location.search({});
Легкий для розуміння та простий спосіб їх очищення.


0

Прийнята відповідь працювала для мене, але мені потрібно було копати трохи глибше, щоб виправити проблеми із кнопкою "назад".

Що я помітив, це те, що якщо я посилаюсь на сторінку за допомогою <a ui-sref="page({x: 1})">, а потім видаляю рядок запиту за допомогою $location.search('x', null), я не отримую зайвого запису в історії свого браузера, тому кнопка "назад" повертає мене туди, де я почав. Хоча я вважаю, що це неправильно, тому що я не думаю, що Angular повинен автоматично видаляти цей запис історії для мене, це фактично бажана поведінка для мого конкретного випадку використання.

Проблема полягає в тому, що якщо я посилання на сторінку , використовуючи <a href="https://stackoverflow.com/page/?x=1">замість цього, потім видалити рядок запиту таким же чином, я зробити отримати додаткову запис в моїй історії браузера, так що я повинен натиснути на кнопку назад двічі , щоб повернутися туди , де я почав . Це непослідовна поведінка, але насправді це здається більш правильним.

Я легко можу вирішити проблему із hrefпосиланнями, використовуючи $location.search('x', null).replace(), але тоді це порушує сторінку, коли ви приземляєтесь на ній за допомогою ui-srefпосилання, тому це не корисно.

Після безлічі обертів, я придумав це виправлення:

У функції своєї програми runя додав це:

$rootScope.$on('$locationChangeSuccess', function () {
    $rootScope.locationPath = $location.path();
});

Потім я використовую цей код для видалення параметра рядка запиту:

$location.search('x', null);

if ($location.path() === $rootScope.locationPath) {
    $location.replace();
}

0

Для кутових> 2 ви можете передати нуль всім парам, які потрібно очистити

this.router.navigate(['/yourRoute'], {queryParams:{params1: null, param2: null}})
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.