Sayfayı yeniden yüklemeden URL'yi nasıl değiştiririm?


2377

Sayfayı yeniden yüklemeden geçerli sayfanın URL'sini değiştirebilmemin bir yolu var mı?

Mümkünse # karma öncesi bölüme erişmek istiyorum.

Yalnızca alan adından sonra bölümü değiştirmem gerekiyor , bu yüzden alanlar arası politikaları ihlal ettiğim gibi değil.

 window.location.href = "www.mysite.com/page2.php";  // Sadly this reloads

139
Soruyu anlamayı kolaylaştırmak için, örneğin bir fotoğraf açtığınızda Facebook bunu yapar. URL çubuğu, söz konusu fotoğrafa DOĞRUDAN şekilde işaret edecek şekilde değişir, böylece URL'yi sitede nerede olduğunuzu kaybetmeden paylaşabilirsiniz. Son on yıldaki çerçevelere dayanan siteleri hatırlıyor musunuz? Yalnızca ana sayfa URL'sini alabilirsiniz, çünkü yalnızca dahili çerçeveler değişiyordu. Ve bu korkunçtu.
Spidey

history.pushState()Muhtemelen burada doğru cevap olsa da, bu durumda (kesin koşullara bağlı olarak ...) bir sunucu tarafı yönlendirme kullanma olasılığı (Apache'nin RewriteRule yönergesini kullanmak gibi) dikkate almak isteyebileceğiniz bir şeydir veya en azından haberdar. Sadece bahsedilmesi gerektiğini düşündüm!
Mart'ta Doin

Yanıtlar:


2033

Bu artık Chrome, Safari, Firefox 4+ ve Internet Explorer 10pp4 + 'da yapılabilir!

Daha fazla bilgi için bu sorunun cevabına bakın: Adres çubuğunu karma olmadan yeni URL ile güncelleme veya sayfayı yeniden yükleme

Misal:

 function processAjaxData(response, urlPath){
     document.getElementById("content").innerHTML = response.html;
     document.title = response.pageTitle;
     window.history.pushState({"html":response.html,"pageTitle":response.pageTitle},"", urlPath);
 }

Daha sonra window.onpopstategeri / ileri düğmesi gezinmesini algılamak için kullanabilirsiniz :

window.onpopstate = function(e){
    if(e.state){
        document.getElementById("content").innerHTML = e.state.html;
        document.title = e.state.pageTitle;
    }
};

Tarayıcı geçmişini değiştirmeye daha ayrıntılı bir bakış için bu MDN makalesine bakın .


272
O zaman facebook bunu IE7'de nasıl yapıyor?
Dominic

57
@CHiRiLo , HTML5 geçmiş API'sını desteklemeyen tarayıcılar için bir geri dönüş sağlayan history.js'ye göz atın .
David Murdoch

23
@infensus URL yerde bir # işareti o hile var olan, varsa yıl ..
Izkata

34
"IE10pp4 +" nın "pp4 +" kısmı ne anlama geliyor?
Scott Tesler

34
platform önizleme 4
David Murdoch

587

HTML5 , sırasıyla geçmiş girişlerini eklemenize ve değiştirmenize izin veren history.pushState()ve history.replaceState()yöntemlerini tanıttı .

window.history.pushState('page2', 'Title', '/page2.php');

Bununla ilgili daha fazla bilgiyi buradan okuyun


12
file:///Güvenlik nedeniyle çalışmayabilir , örn. Firefox 30. ile test localhostedin python -m SimpleHTTPServer.
Ciro Santilli 法轮功 at 审查 六四 事件 法轮功

6
İlk parametrenin sadece bir dize değil bir nesne olması beklenir.
Alexis Wilke

40
IMO bu gerçekten en iyi cevap. Tüm yapmak istediğiniz mevcut URL'yi güncellemekse ({}, null, strNewPath) tek yapmanız gereken budur. İf (history.pushState) ile ilk test etmek en iyisi {}
Craig Jacobs

7
değiştirmek istemiyorsanız, ilk 2 parametre için null değerini girebilirsiniz. Üçüncü parametre için de mutlak bir url kullanabilirsiniz.
Andrew

3
Sadece cevabın içine biraz daha bilgi koyarsanız iyi olur. Parametre 1'in ne yaptığı hakkında hiçbir fikrim yok.
RedClover

130

URL'yi değiştirmek ancak girişi tarayıcı geçmişine eklemek istemiyorsanız HTML5 replaceState'i de kullanabilirsiniz :

if (window.history.replaceState) {
   //prevents browser from storing history with each change:
   window.history.replaceState(statedata, title, url);
}

Bu, geri düğmesi işlevini 'bozacaktır'. Bu, her resme kendi benzersiz URL'sini verirken, bir resim galerisi (geri düğmesinin görüntülediğiniz her görüntüde geriye gitmek yerine galeri dizin sayfasına geri dönmesini istediğiniz) gibi bazı durumlarda gerekli olabilir.


110

İşte benim çözümüm (newUrl, mevcut URL ile değiştirmek istediğiniz yeni URL'nizdir):

history.pushState({}, null, newUrl);

1
İlk önce if ile test etmek en iyisi (history.pushState) {} Eski tarayıcıda.
Craig Jacobs

Bu artık Firefox'ta alacağınız işe yaramıyor: İşlem güvenli değil.
kkatusic

Ve kullanıcı bu yaklaşımla bir yer imi bile ayarlayabilir, güzel! Artık kullanıcı girişindeki URL'yi güncelleyebilir ve ayarları ne olursa olsun doğrudan yer imi koyabilir.
kod teli

107

NOT: Bir HTML5 tarayıcısıyla çalışıyorsanız, bu yanıtı yok saymalısınız. Bu şimdi diğer cevaplarda da görüldüğü gibi mümkün.

Sayfayı yeniden yüklemeden tarayıcıdaki URL'yi değiştirmenin bir yolu yoktur . URL, son yüklenen sayfanın ne olduğunu gösterir. Değiştirirseniz ( document.location) sayfa yeniden yüklenir.

Bunun açık bir nedeni, www.mysite.combir banka giriş sayfasına benzeyen bir site yazmanızdır . Sonra tarayıcı URL çubuğunu söyleyecek şekilde değiştirin www.mybank.com. Kullanıcı gerçekten baktığından tamamen habersiz olacaktır www.mysite.com.


33
Etki alanını değiştirmek istemiyorum, sadece yolu ve dosya adını.
TheFlash

5
Tarayıcının etki alanı / sitem ve etki alanı / diğer sitenin kullanıcı tarafından "güvenli" olduğu düşünülmediğinden, bu durum potansiyel güvenlik risklerini durdurmaz. Belki de soru neden URL'yi değiştirmek istersiniz? Bunu kullanıcıdan gizleyecekse, uygulamanızı bir iframe içinde çalıştırabilirsiniz.
Robin Günü

5
Bunu aslında Flash ile yapabilirsiniz. Bir istekte bulunmadan URL'yi değiştirmenize olanak tanır. Bu mümkündür, çünkü Flash tarayıcının dışında çalışır ancak tarayıcıyla çok sıkı çalışır.
Nick Berardi

142
Adres çubuğundaki istemci tarafında URL'yi değiştirmek istemek için mükemmel geçerli nedenler olduğunu söylemeliyim. Örneğin, disk belleği, sıralama ve filtreleme içeren bir veri tablonuz varsa ve bu öğelerin Ajax tarafından desteklenmesini istiyorsanız, ancak sayfanın geçerli durumunun yer imi alabilmesi için yine de URL'yi güncelleyin. Etki alanı adını (kimlik avı vb.) Değiştirerek güvenlik risklerini anlayabiliyorum, ancak tarayıcılar neden üst düzey alanın sağındaki URL'nin sadece bir kısmının komut dosyasıyla değiştirilmesine izin vermiyor?
Pazar Ironfoot

41
bu cevap artık% 100 doğru değil. Ayrıntılar için cevabıma bakın.
David Murdoch

83
parent.location.hash = "hello";

15
URL'yi değiştirmek istiyorum, sadece karma değil - #mydata
TheFlash

42
Hash'i değiştirmek, çerez kullanmadan bir tür durum olduğu, yer imlerine eklenebilir ve tarayıcı geri düğmeleriyle uyumlu olduğu için ajax'ta yararlı olabilir. Gmail bunu günümüzde daha tarayıcı dostu hale getirmek için kullanıyor.
Matthew Lock

@Jarvis: fark nedir?
gürültülü

@noisy Sunucu tarafı izleme, izleme hizmetine açıkça gönderilmedikçe karmaları göremez.
RedYetiCo

bu, örneğin omurga gibi karma üzerinde yönlendiren bir mvc çerçeve kullanıyorsanız yararlı değildir.
catbadger

27

Modern tarayıcılarda ve HTML5'te , pushStatepencerede adı verilen bir yöntem vardır history. Bu, URL'yi değiştirir ve sayfayı yüklemeden geçmişe iter.

Bu şekilde kullanabilirsiniz, 3 parametre, 1) durum nesnesi 2) başlık ve bir URL) alacaktır:

window.history.pushState({page: "another"}, "another page", "example.html");

Bu URL'yi değiştirir, ancak sayfayı yeniden yüklemez. Ayrıca, sayfanın var olup olmadığını kontrol etmez, bu nedenle URL'ye tepki veren bir JavaScript kodu yaparsanız, onlarla bu şekilde çalışabilirsiniz.

Ayrıca history.replaceState(), tam olarak aynı şeyi yapan şey var, ancak yeni bir tarih oluşturmak yerine mevcut geçmişi değiştirecek!

Ayrıca var olup olmadığını kontrol etmek için bir işlev oluşturabilir history.pushState, ardından geri kalanını şu şekilde devam ettirebilirsiniz :

function goTo(page, title, url) {
  if ("undefined" !== typeof history.pushState) {
    history.pushState({page: page}, title, url);
  } else {
    window.location.assign(url);
  }
}

goTo("another page", "example", 'example.html');

Ayrıca , sayfayı yeniden yüklemeyecek olan #for öğesini de değiştirebilirsiniz <HTML5 browsers. Angular, hashtag'e göre SPA yapmak için bu şekilde kullanır ...

Değiştirmek #oldukça kolaydır, şöyle yapmak:

window.location.hash = "example";

Ve bunu şu şekilde tespit edebilirsiniz:

window.onhashchange = function () {
  console.log("#changed", window.location.hash);
}

Misiniz window.onhashchangeve window.onpopstatebu durumda aynı şeyi?
J0ANMM

Sayfa içerikleri de nasıl yüklenir? URL
MD'nin

İçeriği normalde ajax ile yaptığınız gibi yükleyin.
AndroidDev

26

HTML5 replaceState, Vivart ve geo1701 tarafından daha önce belirtildiği gibi cevaptır. Ancak, tüm tarayıcılarda / sürümlerde desteklenmez. History.js, HTML5 durum özelliklerini sarar ve HTML4 tarayıcıları için ek destek sağlar.


24

HTML5'ten önce şunları kullanabiliriz:

parent.location.hash = "hello";

ve:

window.location.replace("http:www.example.com");

Bu yöntem sayfanızı yeniden yükleyecektir, ancak HTML5 history.pushState(page, caption, replace_url), sayfanızı yeniden yüklememesi gereken tanıttı .


2
Sorun history.pushState(..), başka bir alana yönlendirmek istiyorsanız, web alanları arası politikanın yürürlüğe girmesidir. İle iken window.location.replace(..)başka bir etki alanına yönlendirme mümkündür.
OSWorX

23

Yapmaya çalıştığınız kullanıcılar sayfalara yer işareti koyma / paylaşma izni veriyorsa ve bunun tam olarak doğru URL olması gerekmiyorsa ve başka bir şey için karma çapa kullanmıyorsanız, bunu ikide yapabilirsiniz parçaları; yukarıda tartışılan location.hash öğesini kullanırsınız ve daha sonra giriş sayfasında bir karma bağlantı içeren bir URL aramak için bir kontrol uygular ve sizi sonraki sonuca yönlendirirsiniz.

Örneğin:

1) Kullanıcı açık www.site.com/section/page/4

2) Kullanıcı, URL'yi www.site.com/#/section/page/6(karma ile) değiştiren bazı işlemler yapar . Sayfa 6 için doğru içeriği sayfaya yüklediğinizi varsayalım, bu nedenle karma dışında kullanıcı çok rahatsız olmaz.

3) Kullanıcı bu URL'yi başka birine aktarır veya yer imlerine ekler

4) Daha sonraki bir tarihte başka biri veya aynı kullanıcı şu adrese gider: www.site.com/#/section/page/6

5) Kod www.site.com/, kullanıcıyı şu şekilde www.site.com/section/page/6kullanarak yönlendirir :

if (window.location.hash.length > 0){ 
   window.location = window.location.hash.substring(1);
}

Umarım mantıklıdır! Bazı durumlar için yararlı bir yaklaşımdır.


17

Aşağıda, sayfayı yeniden yüklemeden URL'yi değiştirme işlevi verilmiştir. Yalnızca HTML5 için desteklenir.

  function ChangeUrl(page, url) {
        if (typeof (history.pushState) != "undefined") {
            var obj = {Page: page, Url: url};
            history.pushState(obj, obj.Page, obj.Url);
        } else {
            window.location.href = "homePage";
            // alert("Browser does not support HTML5.");
        }
    }

  ChangeUrl('Page1', 'homePage');

2
@Yeşil, sayfa, taşındığınız durum için kısa bir başlıktır. Firefox şu anda bu parametreyi yok sayar, ancak gelecekte de kullanabilir. Boş dizeyi buraya iletmek, yöntemde yapılacak değişikliklere karşı güvenli olmalıdır. Gönderen: developer.mozilla.org/tr-TR/docs/Web/API/…
Snook

13

Konumda yapılan herhangi bir değişiklik (ya window.locationda document.location), yalnızca URL parçasını değiştirmiyorsanız, bu yeni URL'de bir talebe neden olur. URL'yi değiştirirseniz, URL'yi değiştirirsiniz.

Şu anda kullandığınız URL'leri beğenmiyorsanız Apache'nin mod_rewrite gibi sunucu tarafı URL yeniden yazma tekniklerini kullanın .


"Location.pathname" kullanabilir miyim ??
TheFlash

3
Hayır, bu niteliğin değiştirilmesi de bir isteğe neden olacaktır.
Gumbo

11

Bağlantı etiketleri ekleyebilirsiniz. Bunu sitemde kullanıyorum, böylece kullanıcıların sayfada ne ziyaret ettiğini Google Analytics ile takip edebilirim.

Sadece bir tutturucu etiketi ve ardından sayfanın izlemek istediğim kısmını ekliyorum:

var trackCode = "/#" + urlencode($("myDiv").text());
window.location.href = "http://www.piano-chords.net" + trackCode;
pageTracker._trackPageview(trackCode);

9

Thomas Stjernegaard Jeppesen'in işaret ettiği gibi , kullanıcı Ajax bağlantılarınız ve uygulamalarınız arasında gezinirken URL parametrelerini değiştirmek için History.js'yi kullanabilirsiniz .

Bu yanıttan bu yana neredeyse bir yıl geçti ve History.js büyüdü ve daha kararlı ve tarayıcılar arası hale geldi. Artık HTML5 uyumlu birçok HTML4 tarayıcısında geçmiş durumlarını yönetmek için kullanılabilir. Bu demoda nasıl çalıştığına dair bir örnek görebilirsiniz (işlevlerini ve sınırlarını deneyebilmenin yanı sıra).

Bu kütüphaneyi nasıl kullanacağınız ve uygulayacağınız konusunda yardıma ihtiyacınız olursa, demo sayfasının kaynak koduna göz atmanızı öneririm: Yapmanın çok kolay olduğunu göreceksiniz.

Son olarak, hash (ve hashbangs) kullanımıyla ilgili sorunların neler olabileceğine dair kapsamlı bir açıklama için Benjamin Lupton tarafından bu bağlantıya göz atın .



7

Uygulamanızın herhangi bir yerinde bu güzel ve basit işlevi kullanabilirsiniz.

function changeurl(url, title) {
    var new_url = '/' + url;
    window.history.pushState('data', 'Title', new_url);
    document.title = title;
}

URL'yi yalnızca düzenlemekle kalmaz, aynı zamanda başlığı da güncelleyebilirsiniz.

Herkese oldukça yardımcı oldu.


1
Çapalar için bile bir cazibe gibi çalışıyorwindow.history.pushState('data', 'Title', '#new_location');
BIOHAZARD
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.