Routing angularJS tanpa hash '#'

223

Saya belajar AngularJS dan ada satu hal yang sangat mengganggu saya.

Saya gunakan $routeProvideruntuk menyatakan aturan perutean untuk aplikasi saya:

$routeProvider.when('/test', {
  controller: TestCtrl,
  templateUrl: 'views/test.html'
})
.otherwise({ redirectTo: '/test' });

tetapi ketika saya menavigasi ke aplikasi saya di browser saya melihat app/#/testbukan app/test.

Jadi pertanyaan saya adalah mengapa AngularJS menambahkan hash ini #ke url? Apakah ada kemungkinan untuk menghindarinya?

pikkvile
sumber
2
Ini solusinya jika Anda menggunakan Angular 1.6.
Mistalis

Jawaban:

265

Bahkan Anda membutuhkan # (tagar) untuk browser non HTML5.

Kalau tidak, mereka hanya akan melakukan panggilan HTTP ke server di href yang disebutkan. # Adalah sebuah shortcircuit browser lama yang tidak memecat permintaan, yang memungkinkan banyak kerangka kerja js membangun rerouting di sisi klien mereka sendiri.

Anda dapat menggunakan $locationProvider.html5Mode(true)untuk memberitahu sudut untuk menggunakan strategi HTML5 jika tersedia.

Di sini daftar browser yang mendukung strategi HTML5: http://caniuse.com/#feat=history

plus-
sumber
4
Oke terima kasih. Ini adalah sesuatu yang saya duga. Tetapi bagi saya ini cukup user-friendly! Katakanlah saya ingin beberapa sumber tersedia melalui url, app / res. Bagaimana cara pengguna situs saya mengetahui bahwa mereka harus mengetikkan app / # / res?
pikkvile
5
Tetapi jika demikian, mengapa saya perlu jalur ini agar terlihat di bilah lokasi? Jika pengguna tidak akan menggunakannya, saya hanya bisa membuat aplikasi javascript satu halaman.
pikkvile
6
Ini berguna ketika Anda ingin melacak status aplikasi. Kerangka kerja menawarkan mekanisme sejarah. Selain itu, ini memungkinkan akses langsung ke keadaan aplikasi Anda melalui berbagi url misalnya
plus-
6
Tagar tidak diperlukan di browser modern yang mendukung API riwayat HTML5. Lihat jawaban @ skeep dan tautan yang disediakan. Dalam mode HTML5, Angular hanya akan menggunakan tagar jika browser tidak mendukungnya. Catatan juga, Anda tidak harus menggunakan $ routeProvider jika Anda tidak ingin ... Anda dapat memasang routing Anda sendiri menggunakan ng-klik dan ng-include (sebenarnya Anda harus melakukan ini jika Anda membutuhkan beberapa level dari Routing, karena ng-view hanya dapat muncul sekali per halaman). Lihat juga stackoverflow.com/questions/12793609/...
Mark Rajcok
2
Untuk kasus html render hashbang / pushstate / server-side, yang Twitter cukup bagus untuk membaca engineering.twitter.com/2012/12/... Ini menjelaskan bagaimana mereka berhasil melakukannya sehingga kompatibel dengan browser lama dan dengan pencarian. mesin. Saya tahu ini bukan angular khusus tetapi Anda dapat mereproduksi aliran.
jackdbernier
47

Jika Anda mengaktifkan html5mode seperti yang orang lain katakan, dan buat .htaccessfile dengan konten berikut (sesuaikan dengan kebutuhan Anda):

RewriteEngine   On
RewriteBase     /
RewriteCond     %{REQUEST_URI} !^(/index\.php|/img|/js|/css|/robots\.txt|/favicon\.ico)
RewriteCond     %{REQUEST_FILENAME} !-f
RewriteCond     %{REQUEST_FILENAME} !-d
RewriteRule     ./index.html [L]

Pengguna akan diarahkan ke aplikasi Anda ketika mereka memasuki rute yang tepat, dan aplikasi Anda akan membaca rute dan membawa mereka ke "halaman" yang benar di dalamnya.

EDIT: Pastikan saja tidak ada file atau nama direktori yang bertentangan dengan rute Anda.

pacar beruang
sumber
apakah ada versi nginx ini? ketika saya memuat /abouthalaman gagal kecuali saya datang melalui aplikasi.
chovy
Tidak pernah menggunakannya, tetapi coba ini: stackoverflow.com/questions/5840497/convert-htaccess-to-nginx
bearfriend
3
@chovy - ini dia versi nGinx: server {server_name my-app; root / path / ke / app; location / {try_files $ uri $ uri / /index.html; }}
Moin Haidar
4
ingat <base href = "/"> </base> di tag kepala
Silvio Troia
Terima kasih! tanpa ini, tautan yang dalam tidak mungkin. Saya masih tidak yakin dengan kecantikan atau URI yang sepadan dengan kesulitan mempertahankan hal ini jika Anda memerlukan tautan dalam, terutama di beberapa lingkungan cloud / paas di mana Anda mungkin tidak memiliki akses mudah ke konfigurasi httpd.
Pierre Henry
39

Mari kita tulis jawaban yang terlihat sederhana dan pendek

Di Router pada akhirnya tambahkan html5Mode (true) ;

app.config(function($routeProvider,$locationProvider) {

    $routeProvider.when('/home', {
        templateUrl:'/html/home.html'
    });

    $locationProvider.html5Mode(true);
})

Di kepala html tambahkan tag dasar

<html>
<head>
    <meta charset="utf-8">    
    <base href="/">
</head>

terima kasih kepada @plus - untuk merinci jawaban di atas

vijay
sumber
Saya belum bisa menjalankannya. Saya telah memposting pertanyaan baru dengan detail spesifik saya di: stackoverflow.com/questions/36041074/... Silakan lihat ini dan jika Anda dapat membantu saya akan sangat menghargainya.
Larry Martell
30

mencoba

$locationProvider.html5Mode(true)

Info lebih lanjut di $ locationProvider
Menggunakan $ location

skeep
sumber
6
maaf saya menambahkan .config (fungsi ($ locationProvider) {$ locationProvider.html5Mode (true)}) tetapi saya memiliki hasil index.html #% 2Rumah bukan index.html / home
zloctb
12

Informasi berikut ini dari:
https://scotch.io/quick-tips/pretty-urls-in-angularjs-removing-the-hashtag

Sangat mudah untuk mendapatkan URL bersih dan menghapus tagar dari URL di Angular.
Secara default, AngularJS akan merutekan URL dengan tagar Sebagai Contoh:

Ada 2 hal yang perlu dilakukan.

  • Mengkonfigurasi $ locationProvider

  • Menetapkan basis kami untuk tautan relatif

  • $ lokasi Layanan

Di Angular, layanan $ location mem-parsing URL di bilah alamat dan membuat perubahan pada aplikasi Anda dan sebaliknya.

Saya akan sangat merekomendasikan membaca dokumen resmi $ lokasi Angular untuk merasakan layanan lokasi dan apa yang disediakannya.

https://docs.angularjs.org/api/ng/service/$location

$ locationProvider dan html5Mode

  • Kami akan menggunakan modul $ locationProvider dan mengatur html5Mode menjadi true.
  • Kami akan melakukan ini ketika mendefinisikan aplikasi Angular Anda dan mengkonfigurasi rute Anda.

    angular.module('noHash', [])
    
    .config(function($routeProvider, $locationProvider) {
    
       $routeProvider
           .when('/', {
               templateUrl : 'partials/home.html',
               controller : mainController
           })
           .when('/about', {
               templateUrl : 'partials/about.html',
               controller : mainController
           })
           .when('/contact', {
               templateUrl : 'partials/contact.html',
               controller : mainController
           });
    
       // use the HTML5 History API
       $locationProvider.html5Mode(true); });

Apa itu API Sejarah HTML5? Ini adalah cara standar untuk memanipulasi riwayat browser menggunakan skrip. Ini memungkinkan Angular mengubah perutean dan URL halaman kami tanpa menyegarkan halaman. Untuk informasi lebih lanjut tentang ini, berikut adalah Artikel API Sejarah HTML5 yang bagus:

http://diveintohtml5.info/history.html

Pengaturan Untuk Tautan Relatif

  • Untuk menautkan sekitar aplikasi Anda menggunakan tautan relatif, Anda harus mengatur bagian <base>dalam <head>dokumen Anda. Ini mungkin dalam file root index.html aplikasi Angular Anda. Temukan <base>tag, dan atur ke root URL yang Anda inginkan untuk aplikasi Anda.

Sebagai contoh: <base href="https://stackoverflow.com/">

  • Ada banyak cara lain untuk mengonfigurasi ini, dan mode HTML5 yang disetel ke true harus secara otomatis menyelesaikan tautan relatif. Jika root aplikasi Anda berbeda dari url (misalnya / my-base, gunakan itu sebagai basis Anda.

Fallback untuk Browser yang Lebih Lama

  • Layanan $ location akan secara otomatis mundur ke metode hashbang untuk browser yang tidak mendukung API Riwayat HTML5.
  • Ini terjadi secara transparan kepada Anda dan Anda tidak perlu mengkonfigurasi apa pun agar bisa berfungsi. Dari dokumen $ lokasi Angular, Anda dapat melihat metode mundur dan cara kerjanya.

Kesimpulannya

  • Ini adalah cara sederhana untuk mendapatkan URL cantik dan menghapus tagar di aplikasi Angular Anda. Bersenang-senang membuat aplikasi Sudut yang sangat bersih dan super cepat!
zero_cool
sumber
3

Jika Anda ingin mengonfigurasi ini secara lokal pada OS X 10.8 yang melayani Angular dengan Apache, maka Anda mungkin menemukan yang berikut ini di file .htaccess Anda membantu:

<IfModule mod_rewrite.c>
    Options +FollowSymlinks
    RewriteEngine On
    RewriteBase /~yourusername/appname/public/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !.*\.(css|js|html|png|jpg|jpeg|gif|txt)
    RewriteRule (.*) index.html [L]
</IfModule>

Opsi + Tautan FollowSym jika tidak diset dapat memberi Anda kesalahan terlarang dalam log seperti:

Options FollowSymLinks or SymLinksIfOwnerMatch is off which implies that RewriteRule directive is forbidden

Basis penulisan ulang diperlukan jika tidak, permintaan akan diselesaikan ke root server Anda yang secara lokal secara default bukan direktori proyek Anda, kecuali jika Anda telah mengkonfigurasi vhosts Anda secara khusus, jadi Anda perlu mengatur lintasan sehingga permintaan menemukan direktori root proyek Anda. Sebagai contoh pada mesin saya, saya memiliki direktori / Users / me / Sites di mana saya menyimpan semua proyek saya. Seperti pengaturan OS X lama.

Dua baris berikutnya secara efektif mengatakan jika jalur tersebut bukan direktori atau file, jadi Anda perlu memastikan Anda tidak memiliki file atau direktori yang sama dengan jalur rute aplikasi Anda.

Kondisi selanjutnya mengatakan jika permintaan tidak diakhiri dengan ekstensi file yang ditentukan jadi tambahkan apa yang Anda butuhkan di sana

Dan [L] yang terakhir mengatakan untuk melayani file index.html - aplikasi Anda untuk semua permintaan lainnya.

Jika Anda masih memiliki masalah kemudian periksa log apache, itu mungkin akan memberi Anda petunjuk yang berguna:

/private/var/log/apache2/error_log
Tuan P
sumber
Jika Anda menggunakan MAMP sebagai server apache host lokal Anda, pastikan RewriteBase pertama adalah tautan relatif. misalnya RewriteBase / angularjs_site_folder /
David Douglas
3

Menggunakan mode HTML5 memerlukan penulisan ulang URL di sisi server, pada dasarnya Anda harus menulis ulang semua tautan Anda ke titik masuk aplikasi Anda (mis. Index.html). Memerlukan <base>tag juga penting untuk kasus ini, karena memungkinkan AngularJS untuk membedakan antara bagian url yang merupakan basis aplikasi dan jalur yang harus ditangani oleh aplikasi. Untuk informasi lebih lanjut, lihat Panduan Pengembang AngularJS - Menggunakan mode $ location HTML5 Server Side .


Memperbarui

Cara: Mengkonfigurasi server Anda agar berfungsi dengan html5Mode 1

Saat Anda mengaktifkan html5Mode, #karakter tidak akan lagi digunakan di url Anda. The #simbol berguna karena tidak memerlukan konfigurasi sisi server. Tanpa #, url terlihat jauh lebih baik, tetapi juga membutuhkan penulisan ulang sisi server. Berikut ini beberapa contohnya:

Penulisan Ulang Apache

<VirtualHost *:80>
    ServerName my-app

    DocumentRoot /path/to/app

    <Directory /path/to/app>
        RewriteEngine on

        # Don't rewrite files or directories
        RewriteCond %{REQUEST_FILENAME} -f [OR]
        RewriteCond %{REQUEST_FILENAME} -d
        RewriteRule ^ - [L]

        # Rewrite everything else to index.html to allow html5 state links
        RewriteRule ^ index.html [L]
    </Directory>
</VirtualHost>

Nginx Menulis Ulang

server {
    server_name my-app;

    index index.html;

    root /path/to/app;

    location / {
        try_files $uri $uri/ /index.html;
    }
}

Azure IIS Menulis Ulang

<system.webServer>
  <rewrite>
    <rules> 
      <rule name="Main Rule" stopProcessing="true">
        <match url=".*" />
        <conditions logicalGrouping="MatchAll">
          <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
          <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
        </conditions>
        <action type="Rewrite" url="/" />
      </rule>
    </rules>
  </rewrite>
</system.webServer>

Penulisan Ulang Cepat

var express = require('express');
var app = express();

app.use('/js', express.static(__dirname + '/js'));
app.use('/dist', express.static(__dirname + '/../dist'));
app.use('/css', express.static(__dirname + '/css'));
app.use('/partials', express.static(__dirname + '/partials'));

app.all('/*', function(req, res, next) {
    // Just send the index.html for other files to support HTML5Mode
    res.sendFile('index.html', { root: __dirname });
});

app.listen(3006); //the port you want to use

Lihat juga

georgeawg
sumber
1

Di Angular 6, dengan router Anda, Anda dapat menggunakan:

RouterModule.forRoot(routes, { useHash: false })
gpresland
sumber
0

Anda juga dapat menggunakan kode di bawah ini untuk mengalihkan ke halaman utama (rumah):

{ path: '', redirectTo: 'home', pathMatch: 'full'}

Setelah menentukan pengalihan Anda seperti di atas, Anda dapat mengalihkan halaman lain, misalnya:

{ path: 'add-new-registration', component: AddNewRegistrationComponent},
{ path: 'view-registration', component: ViewRegistrationComponent},
{ path: 'home', component: HomeComponent}
Arash
sumber
0

**

Disarankan untuk menggunakan gaya HTML 5 (PathLocationStrategy) sebagai strategi lokasi di Angular

** Karena

  1. Ini menghasilkan URL yang bersih dan SEO Friendly yang mudah dipahami dan diingat pengguna.
  2. Anda dapat memanfaatkan rendering sisi server, yang akan membuat aplikasi kami memuat lebih cepat, dengan merender halaman di server terlebih dahulu sebelum mengirimkannya kepada klien.

Gunakan Hashlocationstrtegy hanya jika Anda harus mendukung browser lama.

Klik di sini untuk tahu lebih banyak

Mahendra Waykos
sumber