Saya menggunakan S3 untuk meng-host aplikasi javascript yang akan menggunakan pushStates HTML5. Masalahnya adalah jika pengguna menandai salah satu URL, itu tidak akan menyelesaikan apa pun. Yang saya butuhkan adalah kemampuan untuk mengambil semua permintaan url dan melayani root index.html di bucket S3 saya, daripada hanya melakukan redirect penuh. Kemudian aplikasi javascript saya dapat mem-parsing URL dan melayani halaman yang tepat.
Apakah ada cara untuk memberi tahu S3 agar melayani index.html untuk semua permintaan URL alih-alih melakukan pengalihan? Ini mirip dengan menyiapkan apache untuk menangani semua permintaan yang masuk dengan menyajikan satu index.html seperti dalam contoh ini: https://stackoverflow.com/a/10647521/1762614 . Saya benar-benar ingin menghindari menjalankan server web hanya untuk menangani rute ini. Melakukan semuanya dari S3 sangat menarik.
Jawaban:
Sangat mudah untuk menyelesaikannya tanpa url hacks, dengan bantuan CloudFront.
sumber
Cara saya bisa membuatnya bekerja adalah sebagai berikut:
Di bagian Edit Aturan Pengalihan dari Konsol S3 untuk domain Anda, tambahkan aturan berikut:
Ini akan mengarahkan ulang semua jalur yang menghasilkan 404 tidak ditemukan ke domain root Anda dengan versi hash-bang path. Jadi http://domainandaanda.com/posts akan dialihkan ke http://domainandaanda.com/#!/posts asalkan tidak ada file di / posting.
Untuk menggunakan pushState HTML5, kita harus menerima permintaan ini dan secara manual membuat pushState yang tepat berdasarkan jalur hash-bang. Jadi tambahkan ini ke bagian atas file index.html Anda:
Ini mengambil hash dan mengubahnya menjadi pushState HTML5. Dari titik ini Anda dapat menggunakan pushStates untuk memiliki jalur non-hash-bang di aplikasi Anda.
sumber
<script language="javascript"> if (typeof(window.history.pushState) == 'function') { window.history.pushState(null, "Site Name", window.location.hash.substring(2)); } else { window.location.hash = window.location.hash.substring(2); } </script>
react-router
solusi itu menggunakan HTML5 pushStates dan<ReplaceKeyPrefixWith>#/</ReplaceKeyPrefixWith>
Ada beberapa masalah dengan pendekatan berbasis S3 / Redirect yang disebutkan oleh orang lain.
Solusinya adalah:
Konfigurasikan aturan halaman kesalahan untuk mesin virtual Cloudfront Anda. Dalam aturan kesalahan tentukan:
Kode Respons HTTP: 200
Konfigurasikan instance EC2 dan setup server nginx.
Saya dapat membantu lebih detail sehubungan dengan pengaturan nginx, tinggalkan saja catatan. Telah mempelajarinya dengan cara yang sulit.
Setelah pembaruan distribusi depan cloud. Batalkan cache cloudfront Anda sekali untuk berada dalam mode murni. Tekan url di browser dan semuanya harus baik.
sumber
If-Modified-Since
permintaan GET dikirim ke asal) - mungkin pertimbangan yang bermanfaat bagi orang yang tidak menginginkan untuk mengatur server seperti pada langkah 5.Ini tangensial, tapi di sini ada tip untuk mereka yang menggunakan perpustakaan Rackt's React Router dengan (HTML5) riwayat browser yang ingin di-host di S3.
Misalkan seorang pengguna mengunjungi
/foo/bear
situs web statis S3-host Anda. Dengan saran David sebelumnya , aturan pengalihan akan mengirimnya ke/#/foo/bear
. Jika aplikasi Anda dibuat menggunakan riwayat browser, ini tidak akan banyak gunanya. Namun aplikasi Anda dimuat pada titik ini dan sekarang dapat memanipulasi sejarah.Termasuk riwayat Rackt dalam proyek kami (lihat juga Menggunakan Riwayat Khusus dari proyek React Router), Anda dapat menambahkan pendengar yang mengetahui jalur riwayat hash dan mengganti jalur yang sesuai, seperti yang diilustrasikan dalam contoh ini:
Untuk rekap:
/foo/bear
ke/#/foo/bear
.#/foo/bear
notasi riwayat.Link
tag akan berfungsi seperti yang diharapkan, seperti semua fungsi riwayat browser lainnya. Satu-satunya downside yang saya perhatikan adalah pengalihan interstitial yang terjadi pada permintaan awal.Ini terinspirasi oleh solusi untuk AngularJS , dan saya curiga dapat dengan mudah disesuaikan dengan aplikasi apa pun.
sumber
browserHistory.listen
Saya melihat 4 solusi untuk masalah ini. 3 yang pertama sudah tercakup dalam jawaban dan yang terakhir adalah kontribusi saya.
Setel dokumen kesalahan ke index.html.
Masalah : badan respons akan benar, tetapi kode status akan menjadi 404, yang menyakitkan SEO.
Tetapkan aturan pengalihan.
Masalah : URL tercemar dengan
#!
dan halaman berkedip saat dimuat.Konfigurasikan CloudFront.
Masalah : semua halaman akan mengembalikan 404 dari asal, jadi Anda harus memilih apakah Anda tidak akan menembolok apa pun (TTL 0 seperti yang disarankan) atau jika Anda akan menembolok dan memiliki masalah saat memperbarui situs.
Prerender semua halaman.
Masalah : pekerjaan tambahan untuk halaman prerender, khususnya ketika halaman sering berubah. Misalnya, situs web berita.
Saran saya adalah menggunakan opsi 4. Jika Anda mempratinjau semua halaman, tidak akan ada 404 kesalahan untuk halaman yang diharapkan. Halaman akan memuat dengan baik dan kerangka kerja akan mengambil kendali dan bertindak secara normal sebagai SPA. Anda juga dapat mengatur dokumen kesalahan untuk menampilkan halaman generik error.html dan aturan pengalihan untuk mengarahkan 404 kesalahan ke halaman 404.html (tanpa hashbang).
Mengenai 403 kesalahan Terlarang, saya tidak membiarkan mereka terjadi sama sekali. Dalam aplikasi saya, saya menganggap bahwa semua file dalam ember host bersifat publik dan saya mengatur ini dengan opsi semua orang dengan izin baca . Jika situs Anda memiliki halaman yang bersifat pribadi, membiarkan pengguna untuk melihat tata letak HTML seharusnya tidak menjadi masalah. Yang perlu Anda lindungi adalah data dan ini dilakukan di backend.
Juga, jika Anda memiliki aset pribadi, seperti foto pengguna, Anda dapat menyimpannya dalam ember lain . Karena aset pribadi memerlukan perawatan yang sama seperti data dan tidak dapat dibandingkan dengan file aset yang digunakan untuk meng-host aplikasi.
sumber
Saya mengalami masalah yang sama hari ini tetapi solusi @ Mark-Nutter tidak lengkap untuk menghapus hashbang dari aplikasi angularjs saya.
Bahkan Anda harus pergi ke Edit Izin , klik Tambahkan lebih banyak izin dan kemudian tambahkan Daftar kanan pada ember Anda untuk semua orang. Dengan konfigurasi ini, AWS S3 sekarang akan, dapat mengembalikan 404 kesalahan dan kemudian aturan pengalihan akan menangkap case dengan benar.
Seperti ini :
Dan kemudian Anda bisa pergi ke Edit Aturan Pengalihan dan tambahkan aturan ini:
Di sini Anda dapat mengganti subdomain.domain.fr HostName dengan domain Anda dan KeyPrefix #! / Jika Anda tidak menggunakan metode hashbang untuk tujuan SEO.
Tentu saja, semua ini hanya akan berfungsi jika Anda sudah memiliki setup html5mode di aplikasi sudut Anda.
sumber
Solusi termudah untuk membuat aplikasi Angular 2+ dilayani dari Amazon S3 dan URL langsung berfungsi adalah dengan menentukan index.html baik sebagai dokumen Indeks dan Kesalahan dalam konfigurasi bucket S3.
sumber
body
tanggapan. Kode status akan menjadi 404 dan itu akan merugikan SEO.body
jika Anda memiliki skrip yang Anda impor di skriphead
tersebut tidak akan berfungsi ketika Anda langsung menekan salah satu sub-rute di situs web Andakarena masalahnya masih ada saya meskipun saya melempar solusi lain. Kasus saya adalah bahwa saya ingin menyebarkan semua permintaan tarik ke s3 secara otomatis untuk pengujian sebelum bergabung membuatnya dapat diakses di [domain saya] / permintaan-tarik / [nomor pr] /
(mis. Www.example.com/pull-requests/822/ )
Sepengetahuan saya, tidak ada skenario s3 aturan skenario akan memungkinkan untuk memiliki beberapa proyek dalam satu ember menggunakan html5 perutean sementara sementara di atas sebagian besar suara saran berfungsi untuk proyek di folder root, itu tidak untuk beberapa proyek di subfolder sendiri.
Jadi saya mengarahkan domain saya ke server saya di mana nginx config berikut melakukan pekerjaan
itu mencoba untuk mendapatkan file dan jika tidak ditemukan menganggap itu adalah rute HTML5 dan mencobanya. Jika Anda memiliki halaman sudut 404 untuk rute yang tidak ditemukan, Anda tidak akan pernah sampai ke @not_found dan membuat Anda membuka halaman 404 sudut bukan file yang ditemukan, yang bisa diperbaiki dengan beberapa jika aturan dalam @get_routes atau sesuatu.
Saya harus mengatakan saya tidak merasa terlalu nyaman di bidang nginx config dan menggunakan regex dalam hal ini, saya dapat ini bekerja dengan beberapa trial and error jadi sementara ini berfungsi saya yakin ada ruang untuk perbaikan dan silakan berbagi pemikiran Anda .
Catatan : hapus aturan pengalihan s3 jika Anda memilikinya dalam konfigurasi S3.
dan btw berfungsi di Safari
sumber
Sedang mencari jenis masalah yang sama. Saya akhirnya menggunakan campuran solusi yang disarankan yang dijelaskan di atas.
Pertama, saya memiliki ember s3 dengan beberapa folder, setiap folder mewakili situs web react / redux. Saya juga menggunakan cloudfront untuk pembatalan cache.
Jadi saya harus menggunakan Aturan Routing untuk mendukung 404 dan mengarahkan mereka ke konfigurasi hash:
Dalam kode js saya, saya harus menanganinya dengan
baseName
konfigurasi untuk react-router. Pertama-tama, pastikan dependensi Anda saling beroperasi, saya telah menginstalhistory==4.0.0
yang tidak kompatibel denganreact-router==3.0.1
.Ketergantungan saya adalah:
Saya telah membuat
history.js
file untuk memuat riwayat:Potongan kode ini memungkinkan untuk menangani 404 yang dikirim oleh server dengan hash, dan menggantinya dalam sejarah untuk memuat rute kami.
Anda sekarang dapat menggunakan file ini untuk mengkonfigurasi toko Anda dan file Root Anda.
Semoga ini bisa membantu. Anda akan melihat dengan konfigurasi ini saya menggunakan injektor redux dan injektor saga homebrew untuk memuat javascript secara asinkronisasi melalui perutean. Jangan pedulikan garis tesis ini.
sumber
Anda sekarang dapat melakukan ini dengan Lambda @ Edge untuk menulis ulang path
Berikut adalah fungsi lambda @ Edge yang berfungsi:
Dalam perilaku cloudfront Anda, Anda akan mengeditnya untuk menambahkan panggilan ke fungsi lambda itu di "Permintaan Penampil"
Tutorial Lengkap: https://aws.amazon.com/blogs/compute/implementing-default-directory-indexes-in-amazon-s3-backed-amazon-cloudfront-origins-using-lambdaedge/
sumber
return callback(null, request);
Jika Anda mendarat di sini mencari solusi yang bekerja dengan React Router dan AWS Amplify Console - Anda sudah tahu bahwa Anda tidak dapat menggunakan aturan pengalihan CloudFront secara langsung karena Amplify Console tidak memaparkan CloudFront Distribution untuk aplikasi.
Solusi, bagaimanapun, sangat sederhana - Anda hanya perlu menambahkan aturan redirect / tulis ulang di Amplify Console seperti ini:
Lihat tautan berikut untuk info lebih lanjut (dan aturan ramah-salin dari tangkapan layar):
sumber
Saya sendiri sedang mencari jawaban untuk ini. S3 tampaknya hanya mendukung pengalihan, Anda tidak bisa hanya menulis ulang URL dan secara diam-diam mengembalikan sumber daya yang berbeda. Saya sedang mempertimbangkan untuk menggunakan skrip build saya untuk membuat salinan index.html saya di semua lokasi jalur yang diperlukan. Mungkin itu juga akan berhasil untuk Anda.
sumber
Hanya dengan memberikan jawaban yang sangat sederhana. Cukup gunakan strategi lokasi hash untuk router jika Anda hosting di S3.
export const AppRoutingModule: ModuleWithProviders = RouterModule.forRoot (rute, {useHash: true, scrollPositionRestoration: 'enabled'});
sumber