AngularJS: Làm cách nào để xóa tham số truy vấn trong URL?


135

Ứng dụng AngularJS của tôi cần có quyền truy cập vào hồ sơ LinkedIn của người dùng. Để thực hiện điều đó, tôi cần chuyển hướng người dùng đến URL LinkedIn có chứa tham số redirect_uri gọi lại để thông báo cho LinkedIn chuyển hướng người dùng trở lại ứng dụng web của tôi và bao gồm thông số truy vấn "mã" trong URL. Đó là dòng chảy Oauth 2.0 truyền thống.

Mọi thứ hoạt động tuyệt vời ngoại trừ việc LinkedIn chuyển hướng người dùng quay lại URL sau:

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

Tôi muốn xóa ?code=XXX&state=YYYkhỏi URL để làm cho nó sạch sẽ. Người dùng không cần phải xem các tham số truy vấn tôi nhận được từ chuyển hướng LinkedIn.

Tôi đã thử $location.absUrl($location.path() + $location.hash()).replace(), nhưng nó giữ các thông số truy vấn trong URL.

Tôi cũng không thể trích xuất các tham số truy vấn, ví dụ: "mã", bằng cách sử dụng ($location.search()).code. Có vẻ như có? trước # trong URL ở trên là đánh lừa Angular.

Câu trả lời:


151

tôi sử dụng

$location.search('key', null)

Vì điều này không chỉ xóa khóa của tôi mà còn xóa nó khỏi khả năng hiển thị trên URL.


2
điều này gây ra một vòng lặp nút quay lại trong chrome như trong nút quay lại quay lại //example.com?key=value, nhưng chuyển tiếp góc tới //example.com. Gợi ý?
jaybro

2
Điều này nghe có vẻ giống như vấn đề mã với tôi. Angular không nên chuyển tiếp bất cứ điều gì, trừ khi có một số vua phương pháp được thêm vào bởi bạn. Ngoài ra, thêm .replace () thay thế mục lịch sử hiện tại.
Julius

viewModelHelper.navigateTo ('foo /'); đã duy trì chuỗi truy vấn vào url foo, vì vậy tôi đã sửa nó bằng cách sử dụng window.location.href = 'foo /'; thay thế.
jaybro

2
Không sử dụng cửa sổ, thay vào đó hãy sử dụng cửa sổ $ của Angular. Nó sẽ dễ dàng hơn để kiểm tra đơn vị. Thêm: docs.angularjs.org/api/ng/service/$window
Julius

Anwers này hoạt động hoàn hảo nếu bạn muốn xóa một thông số đặc biệt, cảm ơn.
Dexxo

107

Tôi cuối cùng đã nhận được câu trả lời từ diễn đàn AngularJS. Xem chủ đề này để biết chi tiết


Liên kết là một chuỗi Google Groups, rất khó đọc và không cung cấp câu trả lời rõ ràng. Để xóa tham số URL, hãy sử dụng

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

Tôi nghĩ rằng bạn có nghĩa là đặt đường dẫn trong $ location.url () thay vì $ location.path. Cố gắng hợp nhất cả hai như trên không làm việc cho tôi.
mbdev

1
không làm việc cho tôi quá. Cả hai hàm đều để lại truy vấn param.
Pablo Ezequiel Leone

câu trả lời hữu ích thực sự. Trong kịch bản của tôi, mỗi lần sau lần đầu tiên tôi kích hoạt $ location.path ('/ reportmaint'). Tìm kiếm ({<myparams>}), nó không bao giờ xóa sạch các tham số truy vấn trước đó.
bob.mazzo

điều này gây ra một vòng lặp nút quay lại trong chrome như trong nút quay lại quay lại //example.com?key=value, nhưng chuyển tiếp góc tới //example.com. Gợi ý?
jaybro

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

70

Để xóa TẤT CẢ các tham số truy vấn, hãy làm:

$location.search({});

Để xóa MỘT tham số truy vấn cụ thể, hãy làm:

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

2
Hoạt động cho Angular 1.5 là tốt.
Manish M Demblani 30/03/2016

1
cũng hoạt động với undefined, trong trường hợp bạn đang tránh sử dụng nullnhư tôi.
HankScorpio

Điều tôi không thích là nếu bạn quay lại bằng nút quay lại của trình duyệt, bạn sẽ mất truy vấn tìm kiếm mà tôi đã làm trước đây trong trang tìm kiếm trước đây của tôi.
Gino

@Gino Để giải quyết vấn đề, bạn có thể thêm bản ghi vào lịch sử trình duyệt trước khi thiết lập lại này. stackoverflow.com/q/10541388/586051
Rahul Desai

@RahulDesai Tôi đang sử dụng ng-route, tôi rất khó để nó tự động thực hiện
Gino

29

Để xóa một mục xóa nó và gọi $$ soạn

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

có nguồn gốc từ nguồn angularjs: https://github.com/angular/angular.js/blob/c77b2bcca36cf199478b8fb651972a1f650f646b/src/ng/location.js#L419-L443


2
xuất sắc! Làm việc như người ở.
paulcpederson

Điều này hiệu quả với tôi, nhưng tôi cho rằng giải pháp của Julius là chính xác hơn, vì dường như đó là điều mà các anh chàng Angular đã nghĩ đến khi họ tạo ra searchphương pháp này. docs.angularjs.org/api/ng/service/$location#search
zmilojko

1
Cảm ơn, điều này đã hoạt động khá tốt ... Thật thú vị, IE8 thích đặt / soạn URL đó và sau đó tải nó sau đó. Tôi chắc chắn đây là lý do tại sao định tuyến thích hợp được ưa thích và cũng là lý do tại sao tất cả chúng ta đều là người xấu. : P
Romanulus 16/2/2015

27

Bạn có thể xóa một tham số truy vấn cụ thể bằng cách sử dụng:

delete $location.$$search.nameOfParameter;

Hoặc bạn có thể xóa tất cả các tham số truy vấn bằng cách đặt tìm kiếm vào một đối tượng trống:

$location.$$search = {};

2
Tôi không biết tại sao, nhưng giải pháp này không hoạt động tốt trong khi chuyển qua các trang (các tham số có thể xuất hiện lại, ngay cả khi $location.$$search = {}được thực thi). Giải pháp @basarat đang hoạt động tốt.
Mik378

1
Làm việc tốt với tôi - có thể kiểm tra trình tự bạn đang xóa tham số và thay đổi đường dẫn?
demaniak

1
Mặc dù điều này có thể hoạt động nhưng nó truy cập các biến riêng không cần sửa đổi, hãy xem câu trả lời @Julius cho một giải pháp khác
Ben Taliadoros

26

Tại thời điểm viết và như được đề cập trước đây bởi @Bosh, html5modephải truecó thể đặt $location.search()và được phản ánh lại vào URL trực quan của cửa sổ.

Xem https://github.com/angular/angular.js/issues/1521 để biết thêm thông tin.

Nhưng nếu html5mode true bạn có thể dễ dàng xóa chuỗi truy vấn của URL bằng:

$location.search('');

hoặc là

$location.search({});

Điều này cũng sẽ thay đổi URL hình ảnh của cửa sổ.

(Đã thử nghiệm trong phiên bản AngularJS 1.3.0-rc.1với html5Mode(true).)


12

Cần làm cho nó hoạt động khi html5mode= false?

Tất cả các câu trả lời khác chỉ làm việc khi góc của html5modetrue. Nếu bạn đang làm việc bên ngoài html5mode, thì $locationchỉ đề cập đến vị trí "giả" sống trong hàm băm của bạn - và vì vậy $location.searchkhông thể xem / chỉnh sửa / sửa các thông số tìm kiếm của trang thực tế.

Đây là một cách giải quyết, được chèn vào HTML của trang trước khi tải các góc:

<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
Một cách khác tôi tránh cấu hình html5Mode thành true là tạo chuỗi truy vấn sao cho nó chứa # ngay trước dấu ? . vì vậy hãy myapp/#?client=clientName thay thế myapp/?client=clientName
Angel Gao


4

Nếu bạn muốn chuyển sang một URL khác và xóa các tham số truy vấn, chỉ cần sử dụng:

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

1

Nếu bạn đang sử dụng tham số tuyến đường, chỉ cần xóa $ routeParams

$routeParams= null;

1
Điều này sẽ chỉ đặt biến cục bộ $routeParamsthành null. Không thực sự ảnh hưởng đến các tham số URL trong thanh địa chỉ.
Eric F.

1

Làm thế nào về việc chỉ cần đặt băm vị trí thành null

$location.hash(null);

0

nếu bạn xử lý các tham số ngay lập tức và sau đó chuyển sang trang tiếp theo, bạn có thể đặt dấu chấm hỏi ở cuối vị trí mới.

ví dụ: nếu bạn đã thực hiện $ location.path ('/ nextPage');

thay vào đó, bạn có thể làm điều này: $ location.path ('/ nextPage?');


0

Tôi đã thử các câu trả lời trên nhưng không thể làm cho chúng hoạt động. Mã duy nhất làm việc cho tôi là$window.location.search = ''


0

Tôi có thể thay thế tất cả các tham số truy vấn bằng dòng đơn này: Cách $location.search({});
dễ hiểu và dễ dàng để xóa chúng.


0

Câu trả lời được chấp nhận làm việc cho tôi, nhưng tôi cần đào sâu hơn một chút để khắc phục các vấn đề với nút quay lại.

Điều tôi nhận thấy là nếu tôi liên kết đến một trang bằng cách sử dụng <a ui-sref="page({x: 1})">, sau đó xóa chuỗi truy vấn bằng cách sử dụng $location.search('x', null), tôi không nhận được một mục nhập thêm trong lịch sử trình duyệt của mình, vì vậy nút quay lại đưa tôi trở lại nơi tôi bắt đầu. Mặc dù tôi cảm thấy như vậy là sai vì tôi không nghĩ rằng Angular sẽ tự động xóa mục lịch sử này cho tôi, đây thực sự là hành vi mong muốn cho trường hợp sử dụng cụ thể của tôi.

Vấn đề là nếu tôi liên kết đến trang sử dụng <a href="https://stackoverflow.com/page/?x=1">thay vào đó, sau đó loại bỏ các chuỗi truy vấn trong cùng một cách, tôi làm được một mục thêm trong lịch sử trình duyệt của tôi, vì vậy tôi phải nhấp vào nút quay lại hai lần để có được trở lại nơi tôi bắt đầu . Đây là hành vi không nhất quán, nhưng thực sự điều này có vẻ đúng hơn.

Tôi có thể dễ dàng khắc phục sự cố với hrefcác liên kết bằng cách sử dụng $location.search('x', null).replace(), nhưng sau đó điều này sẽ phá vỡ trang khi bạn truy cập vào nó thông qua một ui-srefliên kết, vì vậy điều này là không tốt.

Sau rất nhiều lần nghịch ngợm, đây là cách khắc phục tôi đã nghĩ ra:

Trong runchức năng của ứng dụng, tôi đã thêm cái này:

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

Sau đó, tôi sử dụng mã này để loại bỏ tham số chuỗi truy vấn:

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

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

0

Đối với Angular> 2 , Bạn có thể truyền null cho tất cả các thông số bạn muốn xóa

this.router.navigate(['/yourRoute'], {queryParams:{params1: null, param2: null}})
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.