AngularJS:如何清除URL中的查询参数?


135

我的AngularJS应用程序需要有权访问用户的LinkedIn个人资料。为此,我需要将用户重定向到一个LinkedIn URL,该URL包含一个回调redirect_uri参数,该参数将告诉LinkedIn将用户重定向回我的Web应用程序,并在URL中包含一个“代码”查询参数。这是传统的Oauth 2.0流程。

一切工作正常,除了LinkedIn将用户重定向回以下URL:

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

我想?code=XXX&state=YYY从URL中删除以便使其干净。用户不需要查看我从LinkedIn重定向接收到的查询参数。

我试过了$location.absUrl($location.path() + $location.hash()).replace(),但是它使查询参数保留在URL中。

我也无法使用提取查询参数,例如“ code” ($location.search()).code。好像有?在上述网址中的#之前欺骗Angular。

Answers:


151

我用

$location.search('key', null)

因为这不仅删除了我的密钥,而且从URL的可见性中将其删除了。


2
这会导致chrome中的后退按钮循环,因为后退按钮会返回//example.com?key=value,但角度会前进到//example.com。有什么建议吗?
jaybro

2
对我来说,这听起来有点像代码问题。Angular不应该转发任何东西,除非您添加了某种方法之王。另外,添加.replace()会替换当前的历史记录条目。
Julius

viewModelHelper.navigateTo('foo /'); 将查询字符串保留为foo url,因此我使用window.location.href ='foo /';进行了修复。代替。
jaybro

2
不要使用window,而应使用Angular的$ window。单元测试将更容易。更多:docs.angularjs.org/api/ng/service/$window
Julius

如果您想删除特定的参数,此答案非常理想,谢谢。
Dexxo

107

我最终从AngularJS论坛得到了答案。看到这个线程的详细信息


链接指向一个Google网上论坛线程,该线程很难阅读且没有提供明确的答案。要删除URL参数,请使用

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

我认为您的意思是将路径放置在$ location.url()中,而不是$ location.path中。试图像上面那样合并它们对我来说是行不通的。
mbdev 2014年

1
也不适合我 这两个函数都将查询参数保留在那里。
Pablo Ezequiel Leone 2014年

确实有帮助的答案。在我的场景中,每次我第一次触发$ location.path('/ reportmaint')。search({<myparams>})时,它都不会清除先前的查询参数。
bob.mazzo 2014年

这会导致chrome中的后退按钮循环,因为后退按钮会返回//example.com?key=value,但角度会前进到//example.com。有什么建议吗?
jaybro

+1 forThe link is to a Google Groups thread, which is difficult to read and doesn't provide a clear answer
Vlad17年

70

要删除所有查询参数,请执行以下操作:

$location.search({});

要删除一个特定的查询参数,请执行以下操作:

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

2
同样适用于Angular 1.5。
Manish M Demblani '16

1
也适用于undefined,以防您null像我一样避免使用。
HankScorpio

我不喜欢的是,如果您使用浏览器后退按钮返回,则会失去我之前在上一个搜索页面中所做的搜索查询。
吉诺(Gino)

@Gino作为解决方法,您可以在此重置之前将记录添加到浏览器历史记录中。stackoverflow.com/q/10541388/586051
Rahul Desai

@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
辉煌!像魅力一样工作。
paulcpederson 2014年

这对我有用,但是我认为Julius的解决方案更正确,因为这似乎是Angular员工在创建该search方法时所想到的。docs.angularjs.org/api/ng/service/$location#search
zmilojko 2015年

1
谢谢,这工作得很好。有趣的是,IE8喜欢设置/编写该URL,然后再加载它。我确定这就是为什么要选择正确的路由以及我们都是坏人的原因。:P
Romanulus

27

您可以使用以下方法删除特定的查询参数:

delete $location.$$search.nameOfParameter;

或者,您可以通过将search设置为一个空对象来清除所有查询参数:

$location.$$search = {};

2
我不知道为什么,但是这种解决方案在切换页面时效果不佳(即使$location.$$search = {}执行参数也会重新出现)。@basarat解决方案运行良好。
Mik378 2014年

1
对我来说效果很好-也许检查删除参数和更改路径的顺序?
demaniak 2014年

1
尽管这可能会起作用,但是它访问不应修改的私有变量,请参见@Julius答案以寻求另一种解决方案
Ben Taliadoros

26

在撰写本文时,正如@Bosh先前所提到的,html5mode必须true能够设置$location.search()它并将其反映回窗口的可视URL。

有关更多信息,请参见https://github.com/angular/angular.js/issues/1521

但是如果 html5mode 是,true您可以使用以下命令轻松清除URL的查询字符串:

$location.search('');

要么

$location.search({});

这还将更改窗口的可视URL。

(已在AngularJS版本中1.3.0-rc.1进行了测试html5Mode(true)。)


12

需要使它在html5mode= 时起作用false吗?

所有其他的答案只有工作的时候角的html5modetrue。如果您在之外工作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
天使高


4

如果要移至另一个URL并清除查询参数,请使用:

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


1

将位置哈希值设置为null怎么样

$location.hash(null);

0

如果您立即处理参数然后移至下一页,则可以在新位置的末尾添加问号。

例如,如果您要完成$ location.path('/ nextPage');

您可以改为:$ location.path('/ nextPage?');


0

我已经尝试了以上答案,但无法使其正常工作。唯一对我有用的代码是$window.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();
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.