Saya telah bekerja tentang cara membuat SPA dapat dirayapi oleh google berdasarkan instruksi google . Meskipun ada beberapa penjelasan umum, saya tidak dapat menemukan tutorial langkah-demi-langkah yang lebih teliti dengan contoh-contoh aktual. Setelah menyelesaikan ini saya ingin membagikan solusi saya sehingga orang lain juga dapat memanfaatkannya dan mungkin memperbaikinya lebih lanjut.
Saya menggunakan MVC
dengan Webapi
pengontrol, dan Phantomjs di sisi server, dan Durandal di sisi klien dengan push-state
diaktifkan; Saya juga menggunakan Breezejs untuk interaksi data client-server, semuanya sangat saya sarankan, tapi saya akan mencoba memberikan penjelasan yang cukup umum yang juga akan membantu orang menggunakan platform lain.
143
Jawaban:
Sebelum memulai, pastikan Anda memahami apa yang dibutuhkan Google , khususnya penggunaan URL yang cantik dan jelek . Sekarang mari kita lihat implementasinya:
Sisi klien
Di sisi klien Anda hanya memiliki satu halaman html yang berinteraksi dengan server secara dinamis melalui panggilan AJAX. itu tentang SPA. Semua
a
tag di sisi klien dibuat secara dinamis di aplikasi saya, nanti kita akan melihat bagaimana membuat tautan ini terlihat oleh bot google di server. Setiap sepertia
kebutuhan tag untuk dapat memilikipretty URL
dalamhref
tag sehingga bot bahwa google akan merangkak itu. Anda tidak inginhref
bagian itu digunakan ketika klien mengkliknya (meskipun Anda ingin server dapat menguraikannya, kami akan melihatnya nanti), karena kami mungkin tidak ingin halaman baru dimuat, hanya untuk membuat panggilan AJAX mendapatkan beberapa data untuk ditampilkan di bagian halaman dan mengubah URL melalui javascript (misalnya menggunakan HTML5pushstate
atau denganDurandaljs
). Jadi, kami memiliki keduanyahref
atribut untuk google dan jugaonclick
yang melakukan pekerjaan ketika pengguna mengklik tautan. Sekarang, karena saya menggunakanpush-state
saya tidak ingin ada#
di URL, jadia
tag khas mungkin terlihat seperti ini:<a href="http://www.xyz.com/#!/category/subCategory/product111" onClick="loadProduct('category','subCategory','product111')>see product111...</a>
'kategori' dan 'subkategori' mungkin akan menjadi frasa lain, seperti 'komunikasi' dan 'telepon' atau 'komputer' dan 'laptop' untuk toko peralatan listrik. Jelas akan ada banyak kategori dan sub kategori yang berbeda. Seperti yang Anda lihat, tautan langsung ke kategori, sub kategori dan produk, bukan sebagai parameter tambahan ke laman 'toko' tertentu seperti
http://www.xyz.com/store/category/subCategory/product111
. Ini karena saya lebih suka tautan yang lebih pendek dan lebih sederhana. Ini menyiratkan bahwa saya tidak akan ada kategori dengan nama yang sama dengan salah satu 'halaman' saya, yaitu 'Saya tidak akan membahas cara memuat data melalui AJAX (
onclick
bagian), mencarinya di google, ada banyak penjelasan bagus. Satu-satunya hal penting di sini yang ingin saya sebutkan adalah ketika pengguna mengklik tautan ini, saya ingin URL di browser terlihat seperti ini:http://www.xyz.com/category/subCategory/product111
. Dan ini URL tidak dikirim ke server! ingat, ini adalah SPA di mana semua interaksi antara klien dan server dilakukan melalui AJAX, tidak ada tautan sama sekali! semua 'halaman' diimplementasikan pada sisi klien, dan URL yang berbeda tidak membuat panggilan ke server (server tidak perlu tahu bagaimana menangani URL ini jika mereka digunakan sebagai tautan eksternal dari situs lain ke situs Anda, kita akan melihatnya nanti di bagian sisi server). Sekarang, ini ditangani dengan luar biasa oleh Durandal. Saya sangat merekomendasikannya, tetapi Anda juga dapat melewati bagian ini jika Anda lebih suka teknologi lainnya. Jika Anda memilihnya, dan Anda juga menggunakan MS Visual Studio Express 2012 untuk Web seperti saya, Anda dapat menginstal Durandal Starter Kit , dan di sana, dishell.js
, gunakan sesuatu seperti ini:Ada beberapa hal penting yang perlu diperhatikan di sini:
route:''
) adalah untuk URL yang tidak memiliki data tambahan di dalamnya, yaituhttp://www.xyz.com
. Di halaman ini Anda memuat data umum menggunakan AJAX. Sebenarnya tidak adaa
tag sama sekali di halaman ini. Anda akan ingin menambahkan tag berikut sehingga bot bahwa google akan tahu apa yang harus dilakukan dengan itu:<meta name="fragment" content="!">
. Tag ini akan membuat bot google mengubah URLwww.xyz.com?_escaped_fragment_=
yang akan kita lihat nanti.mapUnknownRoutes
masuk. Ini memetakan rute yang tidak diketahui ini ke rute 'toko' dan juga menghapus semua '!' dari URL jika itupretty URL
dihasilkan oleh mesin pencari google. Rute 'toko' mengambil info di properti 'fragmen' dan membuat panggilan AJAX untuk mendapatkan data, menampilkannya, dan mengubah URL secara lokal. Dalam aplikasi saya, saya tidak memuat halaman yang berbeda untuk setiap panggilan seperti itu; Saya hanya mengubah bagian halaman di mana data ini relevan dan juga mengubah URL secara lokal.pushState:true
yang menginstruksikan Durandal untuk menggunakan URL push state.Ini semua yang kami butuhkan di sisi klien. Itu dapat diimplementasikan juga dengan URL hash (di Durandal Anda cukup menghapusnya
pushState:true
). Bagian yang lebih kompleks (setidaknya untuk saya ...) adalah bagian server:Sisi server
Saya menggunakan
MVC 4.5
di sisi server denganWebAPI
pengontrol. Server sebenarnya perlu menangani 3 jenis URL: yang dihasilkan oleh google - keduanyapretty
danugly
dan juga URL 'sederhana' dengan format yang sama dengan yang muncul di browser klien. Mari kita lihat bagaimana melakukan ini:URL yang cantik dan yang 'sederhana' pertama kali ditafsirkan oleh server seolah mencoba mereferensikan pengontrol yang tidak ada. Server melihat sesuatu seperti
http://www.xyz.com/category/subCategory/product111
dan mencari pengontrol bernama 'kategori'. Jadi,web.config
saya menambahkan baris berikut untuk mengarahkan ini ke controller penanganan kesalahan tertentu:Sekarang, ini mengubah URL ke sesuatu seperti:
http://www.xyz.com/Error?aspxerrorpath=/category/subCategory/product111
. Saya ingin URL dikirim ke klien yang akan memuat data melalui AJAX, jadi triknya di sini adalah memanggil pengontrol 'indeks' default seolah-olah tidak mereferensikan pengontrol apa pun; Saya melakukannya dengan menambahkan hash ke URL sebelum semua parameter 'kategori' dan 'subkategori'; URL hash tidak memerlukan pengontrol khusus kecuali pengontrol 'indeks' default dan data dikirim ke klien yang kemudian menghapus hash dan menggunakan info setelah hash untuk memuat data melalui AJAX. Berikut adalah kode pengendali penangan kesalahan:Tapi bagaimana dengan URL Jelek ? Ini dibuat oleh bot google dan harus mengembalikan HTML biasa yang berisi semua data yang dilihat pengguna di browser. Untuk ini saya menggunakan phantomjs . Phantom adalah peramban tanpa kepala yang melakukan peramban di sisi klien - tetapi di sisi server. Dengan kata lain, hantu tahu (antara lain) cara mendapatkan halaman web melalui URL, menguraikannya termasuk menjalankan semua kode javascript di dalamnya (serta mendapatkan data melalui panggilan AJAX), dan memberikan Anda kembali HTML yang mencerminkan DOM. Jika Anda menggunakan MS Visual Studio Express Anda banyak keinginan untuk menginstal hantu melalui ini Link .
Tapi pertama-tama, ketika URL jelek dikirim ke server, kita harus menangkapnya; Untuk ini, saya menambahkan ke folder 'App_start' file berikut:
Ini disebut dari 'filterConfig.cs' juga di 'App_start':
Seperti yang Anda lihat, 'AjaxCrawlableAttribute' merutekan URL yang jelek ke pengontrol bernama 'HtmlSnapshot', dan inilah pengontrol ini:
Yang terkait
view
sangat sederhana, hanya satu baris kode:@Html.Raw( ViewBag.result )
Seperti yang dapat Anda lihat di controller, phantom memuat file javascript bernama di
createSnapshot.js
bawah folder yang saya buat bernamaseo
. Ini adalah file javascript ini:Pertama saya ingin mengucapkan terima kasih kepada Thomas Davis untuk halaman di mana saya mendapatkan kode dasar dari :-).
Anda akan melihat sesuatu yang aneh di sini: hantu terus memuat ulang halaman sampai
checkLoaded()
fungsinya kembali benar. Mengapa demikian? ini karena SPA spesifik saya membuat beberapa panggilan AJAX untuk mendapatkan semua data dan menempatkannya di DOM di halaman saya, dan hantu tidak tahu kapan semua panggilan telah selesai sebelum mengembalikan saya kembali refleksi HTML dari DOM. Apa yang saya lakukan di sini adalah setelah panggilan AJAX terakhir saya tambahkan<span id='compositionComplete'></span>
, sehingga jika tag ini ada saya tahu DOM selesai. Saya melakukan ini sebagai respons terhadapcompositionComplete
acara Durandal , lihat di siniuntuk lebih. Jika ini tidak terjadi dalam 10 detik, saya menyerah (seharusnya hanya membutuhkan waktu satu detik hingga yang paling banyak). HTML yang dikembalikan berisi semua tautan yang dilihat pengguna di peramban. Script tidak akan berfungsi dengan baik karena<script>
tag yang ada di snapshot HTML tidak mereferensikan URL yang tepat. Ini dapat diubah juga di file phantom javascript, tapi saya rasa ini tidak perlu karena HTML snapshort hanya digunakan oleh google untuk mendapatkana
tautan dan bukan untuk menjalankan javascript; link ini melakukan referensi URL yang cukup, dan jika fakta, jika Anda mencoba untuk melihat snapshot HTML di browser, Anda akan mendapatkan error javascript tapi semua link akan bekerja dengan baik dan mengarahkan Anda ke server sekali lagi dengan URL yang cukup saat ini dapatkan halaman yang sepenuhnya berfungsi.Ini dia. Sekarang server tahu cara menangani URL cantik dan jelek, dengan push-state diaktifkan di server dan klien. Semua URL jelek diperlakukan dengan cara yang sama menggunakan hantu sehingga tidak perlu membuat pengontrol terpisah untuk setiap jenis panggilan.
Satu hal yang mungkin lebih memilih untuk perubahan tidak untuk membuat panggilan umum 'kategori / subkategori / produk' tetapi menambahkan 'toko' sehingga link akan terlihat seperti:
http://www.xyz.com/store/category/subCategory/product111
. Ini akan menghindari masalah dalam solusi saya bahwa semua URL yang tidak valid diperlakukan seolah-olah mereka benar-benar panggilan ke pengontrol 'indeks', dan saya kira ini dapat ditangani kemudian di dalam pengontrol 'toko' tanpa tambahan pada yangweb.config
saya perlihatkan di atas. .sumber
Google sekarang dapat membuat halaman SPA: Menghilangkan skema perayapan AJAX kami
sumber
Berikut ini tautan ke rekaman screencast dari kelas Pelatihan Ember.js yang saya selenggarakan di London pada 14 Agustus. Ini menguraikan strategi untuk aplikasi sisi klien Anda dan untuk aplikasi sisi server Anda, serta memberikan demonstrasi langsung tentang bagaimana menerapkan fitur-fitur ini akan memberikan JavaScript Single-Page-App Anda degradasi anggun bahkan untuk pengguna dengan JavaScript dimatikan .
Ini menggunakan PhantomJS untuk membantu merayapi situs web Anda.
Singkatnya, langkah-langkah yang diperlukan adalah:
Setelah langkah ini selesai, terserah backend Anda untuk menyajikan versi statis HTML Anda sebagai bagian dari noscript-tag pada halaman tersebut. Ini akan memungkinkan Google dan mesin pencari lainnya untuk merayapi setiap halaman di situs web Anda, meskipun aplikasi Anda pada awalnya adalah aplikasi satu halaman.
Tautan ke screencast dengan detail lengkap:
http://www.devcasts.io/p/spas-phantomjs-and-seo/#
sumber
Anda dapat menggunakan atau membuat layanan Anda sendiri untuk prerender SPA Anda dengan layanan yang disebut prerender. Anda dapat memeriksanya di prerender.io situs webnya dan pada proyek github- nya (Menggunakan PhantomJS dan merender situs web Anda untuk Anda).
Sangat mudah untuk memulai. Anda hanya perlu mengarahkan permintaan crawler ke layanan dan mereka akan menerima html yang diberikan.
sumber
Anda dapat menggunakan http://sparender.com/ yang memungkinkan Aplikasi Halaman Tunggal dirayapi dengan benar.
sumber