Cara memeriksa apakah pengguna dapat kembali dalam riwayat browser atau tidak

Jawaban:

119

Jawaban singkat: Anda tidak bisa.

Secara teknis ada cara yang akurat, yang akan memeriksa properti:

history.previous

Namun, itu tidak akan berhasil. Masalah dengan ini adalah bahwa di sebagian besar browser ini dianggap sebagai pelanggaran keamanan dan biasanya hanya mengembalikan tidak terdefinisi .

history.length

Adalah properti yang disarankan orang lain ...
Namun , panjangnya tidak berfungsi sepenuhnya karena itu tidak menunjukkan di mana Anda berada dalam sejarah. Selain itu, tidak selalu dimulai pada nomor yang sama. Peramban yang tidak disetel untuk memiliki laman landas, misalnya, mulai dari 0 sedangkan peramban lain yang menggunakan laman landas akan mulai dari 1.

teks alternatif

Sebagian besar waktu tautan ditambahkan yang memanggil:

history.back();

atau

 history.go(-1);

dan itu hanya diharapkan bahwa jika Anda tidak dapat kembali maka mengklik tautan itu tidak menghasilkan apa-apa.

McAden
sumber
Ini info yang bagus, tetapi tidak menyelesaikan masalah. Itu akan menguraikan beberapa kode yang benar-benar berfungsi pada browser apa pun. Mungkin kode yang pertama memeriksa browser yang Anda gunakan.
Santiago Bendavid
5
Apa yang saya katakan adalah bahwa tidak ada jawaban yang pasti. Anda mengatakan pro dan kontra dari setiap pendekatan tetapi tidak bagaimana mendapatkan skrip yang memeriksa browser apa yang Anda gunakan dan secara kondisional mengeksekusi salah satu atau potongan kode lainnya.
Santiago Bendavid
Bolehkah saya tahu apa yang Anda maksud dengan 'Masalah dengan ini adalah bahwa di sebagian besar browser ini dianggap sebagai pelanggaran keamanan' Pengguna lain di utas lain juga menunjukkan bahwa bisa mendapatkan riwayat browser klien melanggar keamanan, tetapi tidak menjelaskan mengapa demikian. Adakah yang bisa memberi contoh apa saja ancaman keamanannya?
Kevin Chandra
Situs web seharusnya tidak dapat mengetahui riwayat pengguna yang dapat mencakup informasi pribadi tidak langsung. Situs dapat menggunakan pelacakan / cookie untuk mengetahui apa yang dilakukan pengguna di situs itu sendiri tetapi mereka tidak boleh, misalnya, diizinkan untuk mencari tahu bank apa yang saya gunakan, sekolah mana yang dikunjungi anak-anak saya, dll ... Oleh karena itu, browser tidak akan mengizinkan akses ke properti itu
McAden
84

Ada cara lain untuk memeriksa - periksa pengarah. Halaman pertama biasanya memiliki pengarah kosong ...

if (document.referrer == "") {
    window.close()
} else {
    history.back()
}
Ron Reiter
sumber
2
Perujuk dapat disembunyikan karena alasan privasi.
Kornel
11
Perujuk selalu kosong saat halaman tidak dimuat oleh tautan tetapi dengan memasukkan URL ke bilah alamat, atau memuat bookmark. Halaman seperti itu pasti dapat memiliki riwayat, ketika tab / jendela browser telah memuat halaman lain sebelumnya!
ygoe
1
Tetapi apakah solusi yang berlaku untuk navigasi di situs web multi halaman
Dan
36
Tidak berfungsi jika jendela dibuka dengan target = "_ blank" untuk memaksa jendela baru. Tombol kembali pada browser tidak akan berfungsi, tetapi akan ada document.referrer
Mike_K
3
Ini tidak akan berfungsi jika Anda berasal dari halaman yang aman (HTTPS) ke halaman tidak aman (HTTP), karena itu akan menghapus pengarah.
Kevin Borders
54

Kode saya membiarkan peramban mundur satu halaman, dan jika gagal, memuat url mundur. Itu juga mendeteksi perubahan hashtag.

Ketika tombol kembali tidak tersedia, url mundur akan dimuat setelah 500 ms, sehingga browser memiliki cukup waktu untuk memuat halaman sebelumnya. Memuat url fallback segera setelah itu window.history.go(-1);akan menyebabkan browser menggunakan url fallback, karena skrip js belum berhenti.

function historyBackWFallback(fallbackUrl) {
    fallbackUrl = fallbackUrl || '/';
    var prevPage = window.location.href;

    window.history.go(-1);

    setTimeout(function(){ 
        if (window.location.href == prevPage) {
            window.location.href = fallbackUrl; 
        }
    }, 500);
}
redelschaap
sumber
6
Saya pikir ini benar-benar memusatkan hati pada pertanyaan, mengapa seseorang peduli dan apa yang sebenarnya bisa dilakukan dengan cara yang dapat diandalkan dan konsisten.
Chris Marisic
1
Ini bekerja sampai saya mengambil url tempat tombol kembali berada dan menempelkannya di tab baru di chrome. Mengklik tombol kembali mengakibatkan dikirim ke tab kosong. :(
karlingen
2
Itu perilaku default Chrome. Anda "mengunjungi" halaman tersebut chrome://newtabdan dengan demikian Anda dapat kembali ke sejarah.
redelschaap
Hati-hati dengan ini karena dengan koneksi jaringan yang lambat Anda akan menekan url mundur secara teratur.
cameck
14

Inilah cara saya melakukannya.

Saya menggunakan acara 'beforeunload' untuk mengatur boolean. Kemudian saya mengatur batas waktu untuk menonton apakah 'sebelumunload' dipecat.

var $window = $(window),
    $trigger = $('.select_your_link'),
    fallback = 'your_fallback_url';
    hasHistory = false;

$window.on('beforeunload', function(){
    hasHistory = true;
});

$trigger.on('click', function(){

    window.history.go(-1);

    setTimeout(function(){
        if (!hasHistory){
            window.location.href = fallback;
        }
    }, 200);

    return false;
});

Tampaknya berfungsi di browser utama (diuji FF, Chrome, IE11 sejauh ini).

Toni Feistauer
sumber
1
Sejauh ini, inilah jawaban terbaik untuk pertanyaan itu. Anda dapat dengan mudah mengganti window.location.href = fallbackdengan window.close()dan bekerja juga.
Vitani
13

Ada cuplikan yang saya gunakan dalam proyek saya:

function back(url) {
    if (history.length > 2) {
        // if history is not empty, go back:
        window.History.back();
    } else if (url) {
        // go to specified fallback url:
        window.History.replaceState(null, null, url);
    } else {
        // go home:
        window.History.replaceState(null, null, '/');
    }
}

FYI: Saya menggunakan History.js untuk mengelola riwayat browser.


Mengapa membandingkan history.length ke nomor 2?

Karena laman awal Chrome dihitung sebagai item pertama dalam riwayat peramban.


Ada beberapa kemungkinan history.lengthdan perilaku pengguna:

  • Pengguna membuka tab kosong baru di browser dan kemudian menjalankan halaman. history.length = 2dan kami ingin menonaktifkan back()dalam hal ini, karena pengguna akan pergi ke tab kosong.
  • Pengguna membuka halaman di tab baru dengan mengklik tautan di suatu tempat sebelumnya. history.length = 1dan sekali lagi kami ingin menonaktifkan back()metode.
  • Dan akhirnya, pengguna mendarat di halaman saat ini setelah memuat ulang beberapa halaman . history.length > 2dan sekarang back()bisa diaktifkan.

Catatan: Saya menghilangkan kasus ketika pengguna mendarat di halaman saat ini setelah mengklik tautan dari situs web eksternal tanpa target="_blank".

Catatan 2: document.referrer kosong ketika Anda membuka situs web dengan mengetikkan alamatnya dan juga ketika situs web menggunakan ajax untuk memuat subhalaman, jadi saya berhenti memeriksa nilai ini dalam kasus pertama.

gregmatys
sumber
Pendekatan ini berhasil bagi saya. Saya sebenarnya menyimpan backback backback statis untuk halaman saya yang saya gunakan pada fallback.
Greg Blass
Tapi, jika Anda kembali, sejarah.
Panjang
Kamu benar, sayangnya. Saya menggunakan cuplikan ini hanya dengan struktur "satu langkah mundur" saja ...
gregmatys
12

ini tampaknya melakukan trik:

function goBackOrClose() {  

    window.history.back();
    window.close(); 

    //or if you are not interested in closing the window, do something else here
    //e.g. 
    theBrowserCantGoBack();

}

Panggil history.back () dan kemudian window.close (). Jika peramban dapat kembali ke riwayat, peramban tidak akan dapat melanjutkan ke pernyataan berikutnya. Jika tidak bisa kembali, itu akan menutup jendela.

Namun, harap dicatat bahwa jika halaman telah dicapai dengan mengetikkan url, maka firefox tidak akan mengizinkan skrip untuk menutup jendela.

xtrahelp.com
sumber
3
Saya menemukan ini tidak berfungsi kecuali saya menggunakan setTimeout dengan penundaan beberapa ratus milidetik atau lebih sebelum mencoba menjalankan pernyataan berikutnya, jika tidak, ia akan tetap berjalan setelah menjalankan history.back ()
Ken Fehling
Saya belum mengalaminya secara pribadi, browser apa itu?
xtrahelp.com
Saya telah bekerja dengan baik dengan fungsi setTimeout di jawaban di bawah ini. mis: setTimeout (function () {window.close ()}, 400);
gilchris
2
window.close()dianggap sebagai risiko keamanan oleh banyak browser modern. Beberapa hanya tidak akan membiarkan Anda melakukannya.
Rudi Kershaw
Anda dapat melakukan apa saja setelah window.history.back (); window.close (); hanyalah sebuah contoh
hariszaman
10

Hati-hati dengan window.history.lengthkarena ini juga termasuk entri untukwindow.history.forward()

Jadi, Anda mungkin memiliki window.history.lengthlebih dari 1 entri, tetapi tidak ada entri riwayat. Ini berarti tidak ada yang terjadi jika Anda menembakwindow.history.back()

Blitzlord
sumber
9

Anda tidak dapat langsung memeriksa apakah tombol kembali dapat digunakan. Anda dapat melihat history.length>0, tetapi itu akan berlaku jika ada halaman di depan halaman saat ini juga. Anda hanya dapat memastikan bahwa tombol kembali tidak dapat digunakan kapan history.length===0.

Jika itu tidak cukup baik, yang bisa Anda lakukan hanyalah menelepon history.back()dan, jika halaman Anda masih dimuat setelahnya, tombol kembali tidak tersedia! Tentu saja itu berarti jika tombol kembali adalah tersedia, Anda baru saja navigasikan jauh dari halaman. Anda tidak boleh membatalkan navigasi onunload, jadi yang bisa Anda lakukan untuk menghentikannya adalah mengembalikan sesuatu onbeforeunload, yang akan menghasilkan prompt besar yang mengganggu. Itu tidak layak.

Sebenarnya itu adalah ide yang sangat buruk untuk melakukan apapun dengan sejarah. Navigasi riwayat adalah untuk browser chrome, bukan halaman web. Menambahkan tautan "kembali" biasanya menyebabkan lebih banyak kebingungan pengguna daripada nilainya.

bobince
sumber
2
tentang panjangnya - bahkan tidak di semua browser. Beberapa browser menghitung halaman saat ini sebagai item riwayat dan mulai dari 1. Anda harus menyertakan deteksi browser.
McAden
Sebenarnya saya pikir itu selalu 1! Itu 0adalah brainstart, saya pikir browser akan selalu merespons 1atau lebih. Ternyata Opera dan IE berpikir sebaliknya — tangkapan yang bagus.
bobince
1
"Navigasi riwayat adalah untuk browser chrome, bukan halaman web" - Setuju
Brian
5

history.lengthtidak berguna karena tidak menunjukkan apakah pengguna dapat kembali dalam sejarah. Browser yang berbeda juga menggunakan nilai awal 0 atau 1 - tergantung pada browser.

Solusi yang berfungsi adalah menggunakan $(window).on('beforeunload'event, tapi saya tidak yakin itu akan berfungsi jika halaman dimuat melalui ajax dan menggunakan pushState untuk mengubah riwayat jendela.

Jadi saya telah menggunakan solusi berikut:

var currentUrl = window.location.href;
window.history.back();
setTimeout(function(){
    // if location was not changed in 100 ms, then there is no history back
    if(currentUrl === window.location.href){
        // redirect to site root
        window.location.href = '/';
    }
}, 100);
Gromo
sumber
Bekerja untuk saya seperti ini: function goBackOrTo (targetUrl) {var currentUrl = window.location.href; window.history.go (-1); setTimeout (function () {// jika lokasi tidak diubah dalam 800 ms, maka tidak ada riwayat kembali jika (currentUrl === window.location.href) {// redirect ke situs root window.location.href = targetUrl; }}, 800); }
alfonx
2

Saya datang dengan pendekatan berikut. Itu menggunakan acara onbeforeunload untuk mendeteksi apakah browser mulai meninggalkan halaman atau tidak. Jika tidak dalam rentang waktu tertentu, itu hanya akan mengarahkan ke fallback.

var goBack = function goBack(fallback){
    var useFallback = true;

    window.addEventListener("beforeunload", function(){
      useFallback = false;
    });

    window.history.back();

    setTimeout(function(){
        if (useFallback){ window.location.href = fallback; }
    }, 100); 
}

Anda dapat memanggil fungsi ini menggunakan goBack("fallback.example.org").

Pascal Raszyk
sumber
1
Saya paling suka ini, saya baru saja berubah windows.onbeforeunloadmenjadi pendengar acara window.addEventListener("beforeunload", function (event) { useFallback = false; });sehingga tidak menimpa jendela.
MiChAeLoKGB
2

Membangun jawaban di sini dan di sini . Saya pikir, jawaban yang lebih konklusif hanya untuk memeriksa apakah ini adalah halaman baru di tab baru.

Jika riwayat halaman lebih dari satu, maka kita dapat kembali ke halaman sebelumnya ke halaman saat ini. Jika tidak, tab tersebut adalah tab yang baru dibuka dan kita perlu membuat tab baru.

Berbeda dengan jawaban yang ditautkan, kami tidak mengecek a referrerkarena tab baru masih memiliki referer.

if(1 < history.length) {
    history.back();
}
else {
    window.close();
}
atw
sumber
1
Terima kasih. Anda menyelamatkan hari saya :).
Bijay Yadav
1

Ada solusi lain yang hampir sempurna, diambil dari jawaban SO lainnya :

if( (1 < history.length) && document.referrer ) {
    history.back();
}
else {
    // If you can't go back in history, you could perhaps close the window ?
    window.close();
}

Seseorang melaporkan bahwa itu tidak berfungsi saat menggunakan target="_blank"tetapi tampaknya bekerja untuk saya di Chrome.

Yonn Trimoreau
sumber
0

browser memiliki tombol kembali dan maju. Saya menemukan solusi untuk pertanyaan ini. tetapi ini akan memengaruhi tindakan penerusan browser dan menyebabkan bug pada beberapa browser.

Ini berfungsi seperti itu: Jika browser membuka url baru, yang belum pernah dibuka, history.length akan bertambah.

sehingga Anda dapat mengubah hash like

  location.href = '#__transfer__' + new Date().getTime() 

untuk mendapatkan url yang tidak pernah ditampilkan, maka history.length akan mendapatkan panjang sebenarnya.

  var realHistoryLength = history.length - 1

tetapi, ini tidak selalu bekerja dengan baik, dan saya tidak tahu mengapa, terutama ketika url otomatis melompat dengan cepat.

gan terhormat
sumber
0

Saya sedang berusaha menemukan solusi dan ini adalah yang terbaik yang bisa saya dapatkan (tetapi berfungsi dengan baik dan ini adalah solusi termudah yang pernah saya temukan di sini).

Dalam kasus saya, saya ingin kembali pada sejarah dengan tombol kembali, tetapi jika halaman pertama yang dibuka pengguna adalah subhalaman dari aplikasi saya, itu akan kembali ke halaman utama.

Solusinya adalah, segera setelah aplikasi dimuat, saya baru saja mengganti status sejarah:

history.replaceState( {root: true}, '', window.location.pathname + window.location.hash)

Dengan cara ini, saya hanya perlu memeriksa history.state.rootsebelum kembali. Jika benar, sebagai gantinya saya membuat penggantian riwayat:

if(history.state && history.state.root)
    history.replaceState( {root: true}, '', '/')
else
    history.back() 
Maxwell sc
sumber
Saya tidak berpikir ada kasus penggunaan lain yang baik. Mungkin bukan ide yang baik Jika Anda ingin memeriksa riwayat di luar aplikasi Anda.
Maxwell sc
-1
var fallbackUrl = "home.php";
if(history.back() === undefined)
    window.location.href = fallbackUrl;
Rejeesh Prarath
sumber
ini terlihat sangat mudah ?! apakah itu diuji pada berbagai browser?
benzkji
di Chrome history.back()adalah undefinedhanya pada halaman tab kosong
gregmatys
-2

Larutan

'use strict';
function previousPage() {
  if (window.location.pathname.split('/').filter(({ length }) => length > 0).length > 0) {
    window.history.back();
  }
}

Penjelasan

window.location.pathnameakan memberi Anda URI saat ini. Misalnya https://domain/question/1234/i-have-a-problemakan memberi /question/1234/i-have-a-problem. Lihat dokumentasi tentang window.location untuk informasi lebih lanjut.

Selanjutnya, panggilan untuk split()memberi kita semua bagian URI itu. jadi jika kita mengambil URI sebelumnya, kita akan memiliki sesuatu seperti ["", "question", "1234", "i-have-a-problem"]. Lihat dokumentasi tentang String.prototype.split () untuk informasi lebih lanjut.

Panggilan ke filter()sini untuk menyaring string kosong yang dihasilkan oleh garis miring ke belakang. Ini pada dasarnya hanya akan mengembalikan URI fragmen yang memiliki panjang lebih besar dari 1 (string tidak kosong). Jadi kita akan memiliki sesuatu seperti ["question", "1234", "i-have-a-question"]. Ini bisa ditulis seperti:

'use strict';
window.location.pathname.split('/').filter(function(fragment) {
  return fragment.length > 0;
});

Lihat dokumentasi tentang Array.prototype.filter () dan tugas Destrukturisasi untuk informasi lebih lanjut.

Sekarang, jika pengguna mencoba untuk kembali saat sedang aktif https://domain/, kami tidak akan memicu pernyataan-if, dan karenanya tidak akan memicu window.history.back()metode sehingga pengguna akan tetap berada di situs web kami. URL ini akan sama dengan []yang memiliki panjang 0, dan 0 > 0salah. Karenanya, diam-diam gagal. Tentu saja, Anda dapat mencatat sesuatu atau melakukan tindakan lain jika Anda mau.

'use strict';
function previousPage() {
  if (window.location.pathname.split('/').filter(({ length }) => length > 0).length > 0) {
    window.history.back();
  } else {
    alert('You cannot go back any further...');
  }
}

Keterbatasan

Tentu saja, solusi ini tidak akan berfungsi jika browser tidak mendukung API Sejarah . Periksa dokumentasi untuk mengetahui lebih banyak tentang hal itu sebelum menggunakan solusi ini.

Amin NAIRI
sumber
-5

Saya tidak yakin apakah ini berhasil dan benar-benar belum diuji, tetapi coba ini:

<script type="text/javascript">

    function goBack() {
        history.back();
    }

    if (history.length > 0) { //if there is a history...
        document.getElementsByTagName('button')[].onclick="goBack()"; //assign function "goBack()" to all buttons onClick
    } else {
        die();
    }
</script>

Dan di suatu tempat di HTML:

<button value="Button1"> //These buttons have no action
<button value="Button2">

EDIT:

Yang juga dapat Anda lakukan adalah meneliti browser apa yang mendukung fungsi belakang (saya pikir semuanya) dan menggunakan objek deteksi browser JavaScript standar yang ditemukan, dan dijelaskan secara menyeluruh, di halaman ini . Kemudian Anda dapat memiliki 2 halaman berbeda: satu untuk "browser yang baik" yang kompatibel dengan tombol kembali dan satu untuk "browser yang buruk" memberitahu mereka untuk memperbarui browser mereka

Lateks
sumber
2
history.backadalah suatu fungsi. Anda ingin memeriksa apakah history.length > 0kemudian kembali denganhistory.back()
pixl coder
3
Juga []di NodeList tidak masuk akal, dan Anda tidak dapat menetapkan string ke pengendali event.
bobince
-8

Periksa apakah window.history.lengthsama dengan 0.

Cristian Sanchez
sumber
6
Bukan cara yang baik, karena sejarah. Panjang tidak memberi tahu Anda di mana Anda berada dalam sejarah ...
Ron Reiter
@Ron Reiter: Ya, saya pikir jawaban teratas dan komentar lain untuk pertanyaan ini telah menetapkan bahwa lebih dari setahun yang lalu ...
Cristian Sanchez