Bisakah saya menggunakan window.location.replace di iframe?


15

Kita dapat menggunakan window.location.replaceuntuk menghindari riwayat, dan menargetkan jangkar pada halaman tanpa memuat ulang halaman, tetapi tidak dalam iframe?

Masalahnya adalah pelanggaran CSP (kebijakan keamanan konten), yang menyatakan script-src 'unsafe-inline'harus diaktifkan. Kecuali saya tidak memiliki CSP yang ditentukan, dan bahkan jika saya mendefinisikan satu dan mengizinkannya script-src 'unsafe-inline'masih memberikan kesalahan pelanggaran yang sama. Hasil yang sama di ie11 / chrome / ff.

Iframe di domain yang sama (di direktori yang sama).

  1. Targetkan iframe di konsol dan gunakan window.location.replace('/samepage.html#onpage_anchor')di konsol.
  2. berhasil. Ini menargetkan jangkar pada halaman tanpa memuat ulang halaman, dan tanpa sejarah.
  3. Letakkan kode yang sama sebaris pada tautan jangkar dan berfungsi.
  4. Gunakan kode yang sama di skrip eksternal, dapatkan kesalahan pelanggaran csp. Ini berfungsi dengan baik jika tidak di iframe.

Saya mencoba membuat CSP untuk mengizinkan tindakan, tetapi bahkan yang paling permisif kebijakan keamanan konten mungkin akan mengizinkannya.


Sunting: jadi saya mengumpulkan contoh pada plunker yang memungkinkan banyak file sehingga saya bisa menggunakan hrefs yang tepat yang merujuk halaman induk / anak.

Catatan tentang contoh plunker:

  1. Masalahnya tidak direproduksi dalam contoh-contoh ini. Script berfungsi dengan baik, bahkan di iframe. Namun, kode yang sama tidak berfungsi di server lokal saya, atau ketika saya menjalankannya langsung di VPS.

  2. Saya menduga pelanggaran CSP tidak dipicu pada plunker karena plunker menyajikan konten ke browser melalui semacam lapisan abstraksi.

  3. Pertama kali Anda mengklik tautan akordeon di induk, itu menyebabkan penyegaran. Ini karena cara halaman pertama kali memuatnya tidak merujuk index.html. Klik berikutnya berfungsi seperti yang diharapkan tanpa memuat ulang halaman. Bukan masalah di iframe karena ini memang merujuk pada child.html

  4. Ini adalah contoh yang baik untuk menunjukkan kode tanpa memerlukan perubahan untuk membuatnya bekerja (seperti dalam kebutuhan untuk mengubah hrefs agar membuatnya bekerja dalam potongan-potongan stackoverflow, disebutkan di bawah). Ini juga bagus karena menunjukkan javascript berfungsi sebagaimana mestinya. Tapi itu tidak menunjukkan masalah sebenarnya. Anda masih perlu memuatnya di editor Anda dan menjalankannya di server lokal atau lingkungan hosting langsung untuk melihat masalah sebenarnya.

Contoh Plunker

Dengan skrip: Tanpa sejarah
Tanpa skrip: Dengan sejarah


Contoh kode yang disederhanakan

Akordeon sederhana dengan satu entri. Cukup untuk mereproduksi masalah.

Mengklik buka / tutup akan memperluas / menutup akordeon, tidak perlu JS. JS harus melakukan hal yang persis sama tetapi tanpa sejarah. Bekerja dengan baik, tetapi tidak dalam iframe.

Catatan cuplikan kode:

  1. Anda dapat menjalankan cuplikan untuk mendapatkan gagasan tentang apa yang saya uraikan, tetapi sebenarnya tidak menunjukkan masalahnya.

  2. Cuplikan tidak berlaku seperti di browser asli, javascript tidak berfungsi.

  3. Cuplikan memperlihatkan kode, tetapi harus dijalankan dalam iframe untuk melihat masalah. Jalankan di luar iframe untuk melihat perbedaannya dan cara kerjanya.

  1. Karena cara tautan bekerja dengan JS (mengganti seluruh url), tautan tersebut sebenarnya harus seperti ini href="https://stackoverflow.com/thispage.html#ac1"daripada hanya href="#ac1"seperti yang ditampilkan di cuplikan (tidak dapat menargetkan laman html aktual di cuplikan). Jadi, jika Anda mencoba ini di editor Anda (silakan lakukan), maka ingatlah untuk mengubah tautan ke format ini this_document.html#anchor sehingga mereka tetap jangkar halaman yang sama, tetapi page.html termasuk dalam tautan.


Naskah

$(document).ready(function() {

      // anchor links without history
      $.acAnch = function(event) {
        event.preventDefault();
        var anchLnk = $(event.target);
        var anchTrgt = anchLnk.attr('href');
        window.location.replace(anchTrgt);
      }
      // listen for anchor clicks
      $('.accordion').on('click', 'a', $.acAnch);

    });

Ini sangat sederhana:
1. fungsi acAnch mengambil hrefatribut dan memasukkannya ke dalam window.location.replace().
2. Dengarkan klik pada jangkar dalam akordeon untuk menjalankan fungsi acAnch.

Jadi semua skrip dijalankan window.location.replace('/this_same_page.html#on_page_anchor')

Jika Anda meletakkannya di konsol berfungsi, tidak ada pelanggaran CSP. Tetapi menjalankannya dari skrip eksternal tidak berfungsi.

Inline pada tautan berfungsi dengan baik:

onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"

Menempatkannya di masing-masing tautan berfungsi dengan baik , tetapi saya benar-benar memilih untuk tidak menggunakan skrip inline seperti itu. Pasti ada cara untuk melakukan ini dengan skrip eksternal.

Saya mencoba menjalankan javascript pada orang tua alih-alih di iframe (dengan modifikasi untuk memilih tautan di dalam anak tentu saja). Hasil kesalahan CSP yang sama.


Mengapa aku melakukan ini?

Nah situs ini jauh lebih kompleks daripada contohnya. Jangkar di iframe berfungsi dengan baik tetapi mereka menambah riwayat.Jika Anda menjalankan kode di atas tanpa javascript, (atau hanya menjalankan snippet), buka dan tutup akordeon beberapa kali, dan gunakan tombol kembali, itu akan kembali melalui status buka tutup.

Saya tidak akan keberatan dengan sejarah, tetapi jika itu ada dalam iframe, ketika Anda meninggalkan halaman induk dan kemudian kembali ke sana, sejarah di iframe rusak. Kembali tidak akan kembali melalui negara akordeon lagi, tetapi sebaliknya hanya memuat ulang iframe. Awalnya jangkar tidak menyebabkan iframe reload tetapi hanya langkah melalui sejarah negara akordeon, yang berfungsi dengan baik, sampai Anda meninggalkan halaman dan kembali. Kemudian kembali tidak lagi melewati negara akordeon, tetapi hanya melewati tumpukan israme identik memuat kembali. Ini adalah perilaku pengguna yang sangat tidak ramah.

Saya tidak perlu menggunakan location.replace jika ada metode lain yang akan berfungsi. Saya telah mencoba banyak pendekatan lain, dan saya telah menemukan bahwa metode yang dapat mencapai hasil yang sama, umumnya menghasilkan kesalahan yang sama.

Tujuannya hanya untuk mengaktifkan tautan jangkar di laman tanpa memuat ulang, dan tanpa riwayat, di dalam iframe.

Skrip inline berfungsi. Bisakah kita membuatnya berfungsi dalam file .js eksternal?


apakah Anda mencoba mencapai jangkar? jika demikian, <a href="#ac0" class="ac-close">Close</a>harus bekerja.
Demensik

Oke, saya menyiapkan contoh pada plunker. Sayangnya, masalahnya tidak direproduksi di plunker. Alih-alih, skrip berfungsi dengan baik, bahkan dalam iframe. dengan skrip - tanpa riwayat dan tanpa skrip memiliki riwayat . Masalah kecil pada plunker; tautan akordeon pada induk menyebabkan penyegaran laman, hanya yang pertama kali diklik (awalnya memotong tanpa referensi index.html, jadi setelah klik pertama, itu berfungsi seperti yang diharapkan, tanpa memuat kembali laman). Bukan masalah untuk iframe karena dimuat dengan child.html src.
Veneseme Tyras

Jadi setidaknya dengan contoh plunker Anda dapat melihat kode lengkap dan melihat bagaimana cara kerjanya. Itu tidak bekerja di server lokal saya, atau ketika saya menjalankannya langsung di VPS. Saya akan memperbarui pertanyaan dengan tautan dan info plunker.
Veneseme Tyras

1
Saya mengambil kode sampel Anda ke server saya berfungsi baik, kemudian saya membuat contoh plunker baru dari contoh Anda plnkr.co/edit/V3kx7LQbTppaQ6V06uZp?p=preview itu juga berfungsi dengan baik. Tidak ada hasil kesalahan CSP.
Pemikir

Ya, itu berfungsi dengan baik pada plunker yang saya lakukan juga. Saya ingin tahu bagaimana cara kerjanya di server Anda, karena setelah komentar Anda, saya tiga kali diperiksa dan saya tidak bisa membuatnya bekerja di server langsung saya, atau di server lokal saya.
Veneseme Tyras

Jawaban:



Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.