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

141

我的AngularJS应用程序需要访问用户的LinkedIn资料。为了实现这一点,我需要将用户重定向到一个LinkedIn URL,其中包含一个回调redirect_uri参数,该参数将告诉LinkedIn将用户重定向回我的Web应用程序,并在URL中包括一个“code”查询参数。这是传统的Oauth 2.0流程。

除了LinkedIn将用户重定向回以下URL之外,一切都很顺利:

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

为了使URL更加干净,我希望删除其中的?code=XXX&state=YYY。用户不需要看到我从LinkedIn重定向接收到的查询参数。

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

我也无法提取查询参数,例如"code",使用($location.search()).code。似乎在上面的URL中,"#"前面的"?"是欺骗Angular的。

15个回答

157

我使用

$location.search('key', null)

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


2
这会在Chrome中导致后退按钮循环,因为后退按钮返回到//example.com?key=value,但Angular会转发到//example.com。有什么建议吗? - jaybro
2
这对我来说听起来有点像代码问题。Angular 不应该转发任何东西,除非你添加了某种方法。此外,添加 .replace() 会替换当前的历史记录条目。 - Julius
viewModelHelper.navigateTo('foo/'); 会将查询字符串保留到 foo url 中,所以我改用 window.location.href = 'foo/'; 来解决这个问题。 - jaybro
2
不要使用window,改用Angular的$window。这样更容易进行单元测试。更多信息:https://docs.angularjs.org/api/ng/service/$window - Julius
如果您想删除特定参数,此答案非常完美,谢谢。 - Dexxo
显示剩余2条评论

110

我最后从 AngularJS 论坛上得到了答案。请查看此帖子以获取详细信息。


这个链接指向一个 Google Groups 的帖子,很难阅读并且没有提供明确的答案。要删除 URL 参数,请使用

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

1
我认为你想把路径放在$location.url()里而不是$location.path()里。尝试像上面那样合并它们对我来说行不通。 - mbdev
1
对我也不起作用。两个函数都会保留查询参数。 - Pablo Ezequiel Leone
确实是一份有帮助的回答。在我的情况下,每次第一次触发 $location.path('/reportmaint').search({<myparams> }) 之后,它都没有清除先前的查询参数。 - bob.mazzo
这会在Chrome中导致后退按钮循环,因为后退按钮返回到//example.com?key=value,但Angular会转发到//example.com。有什么建议吗? - jaybro
1
+1 表示“这个链接是一个 Google Groups 的帖子,很难阅读并且没有提供明确的答案”。 - Vlad

80

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

$location.search({});

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

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

2
同样适用于Angular 1.5。 - Manish M Demblani
1
同样适用于undefined,以防您像我一样避免使用null - HankScorpio
我不喜欢的是,如果你使用浏览器的后退按钮返回,你就会失去我在上一页搜索页面中刚刚输入的搜索查询。 - Gino
@Gino 作为一种解决方法,您可以在重置之前向浏览器历史记录中添加一条记录。https://dev59.com/EWkv5IYBdhLWcg3wghIh - Rahul Desai
@RahulDesai 我正在使用ng-route,我认为它会自动完成。 - Gino
只有在路由中添加 reloadOnSearch:false,这个才对我起作用(Angular 1.5)。 - James Bell

29

2
太棒了!像魔法一样顺利地工作了。 - paulcpederson
这对我有用,但我认为Julius的解决方案更正确,因为它似乎是Angular团队在创建search方法时所考虑的。https://docs.angularjs.org/api/ng/service/$location#search - zmilojko
2
谢谢,这个很好用...有趣的是,IE8喜欢设置/组合URL,然后随后加载它。我相信这就是为什么正确的路由是首选,也是我们都是坏人的原因。 :P - RomoCode
请注意,任何以$$为前缀的方法/变量在AngularJS中都不被视为公共API,因此可能会在发布版本之间发生更改/破坏而没有通知。虽然AngularJS现在处于LTS模式,并且在不久的将来不太可能收到除安全补丁之外的任何内容,但通常情况下仍有足够的理由避免尽可能使用这些接口,因为它们被认为是“内部”实现细节。 - runderworld

27

在写作时,正如@Bosh之前提到的那样,html5mode必须为true才能设置$location.search()并反映到窗口的可视URL中。

请参见https://github.com/angular/angular.js/issues/1521获取更多信息。

但是,如果html5modetrue,您可以使用以下方法轻松清除URL的查询字符串:

$location.search('');
或者
$location.search({});

这也会改变窗口的可视URL。

(在AngularJS版本1.3.0-rc.1中测试,使用html5Mode(true)。)


27

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

delete $location.$$search.nameOfParameter;

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

$location.$$search = {};

2
我不知道为什么,但是在切换页面时,这个解决方案不能很好地工作(即使执行了 $location.$$search = {},参数也可能重新出现)。@basarat的解决方案运行良好。 - Mik378
1
对我来说工作得很好,也许你可以检查一下移除参数和更改路径的顺序? - demaniak
1
虽然这可能有效,但它访问了不应该被修改的私有变量,请参考@Julius的答案获取另一种解决方案。 - Ben Taliadoros

12

如何在 html5mode = false 时使其工作?

其他所有答案仅在 Angular 的 html5modetrue 时才有效。 如果你是在 html5mode 之外工作,那么 $location 仅指向存在于哈希中的 “虚拟” 地址,因此 $location.search 无法查看/编辑/修复实际页面的查询参数。

以下是一种解决方法,需要在加载 angular 之前插入页面的 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

6
如果您想跳转到另一个URL并清除查询参数,请使用以下命令:

window.location.href = 'newUrl'

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

5

只需使用

$location.url();

与其

$location.path();

1
如果您正在使用路由参数,只需清除 $routeParams。
$routeParams= null;

1
这只会将本地变量 $routeParams 设置为 null,实际上并不会影响地址栏中的 URL 参数。 - Eric Ferreira

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接