'#' Karması olmadan AngularJS yönlendirme


223

AngularJS öğreniyorum ve beni gerçekten sinirlendiren bir şey var.

Kullandığım $routeProviderUygulamam için kuralları yönlendirme ilan etmek:

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

ancak tarayıcıda uygulamama gittiğimde app/#/testbunun yerine görüyorum app/test.

Öyleyse sorum şu: AngularJS neden bu karmayı URL'lere ekliyor #? Bundan kaçınmak için herhangi bir olasılık var mı?


2
Angular 1.6 kullanıyorsanız çözüm burada .
Mistalis

Yanıtlar:


265

Aslında HTML5 olmayan tarayıcılar için # (hashtag) gerekir.

Aksi takdirde, söz konusu href'de sunucuya bir HTTP çağrısı yaparlar. # Eski bir tarayıcı kısa devresidir.

Sen kullanabilirsiniz $locationProvider.html5Mode(true)varsa HTML5 stratejisini kullanmaya açısal anlatmak için.

HTML5 stratejisini destekleyen tarayıcının listesi: http://caniuse.com/#feat=history


4
Tamam teşekkürler. Bu benim şüphelendiğim bir şey. Ama bana gelince bu oldukça kullanıcı dostu! Diyelim ki bazı kaynakların url, app / res aracılığıyla kullanılabilir olmasını istiyorum. Sitemin kullanıcıları bunun yerine app / # / res yazmaları gerektiğini nasıl öğrenebilir?
pikkvile

5
Ancak öyleyse, neden bu yolların konum çubuğunda görünür olması gerekiyor? Kullanıcılar bunları kullanmazsa, sadece tek sayfalık javascript uygulaması yapabilirim.
pikkvile

6
Uygulama durumunu takip etmek istediğinizde kullanışlıdır. Çerçeveler bir tarih mekanizması sunar. Buna ek olarak, örneğin url paylaşımı yoluyla uygulamanızın durumuna doğrudan erişim sağlar
artı

6
HTML5 geçmiş API'sını destekleyen modern tarayıcılarda hashtag gerekmez. @ Skeep'in cevabına ve sağlanan bağlantılara bakın. HTML5 modunda, Angular yalnızca tarayıcı desteklemiyorsa hashtag'leri kullanır. Ayrıca unutmayın, eğer istemiyorsanız $ routeProvider'ı kullanmak zorunda değilsiniz ... ng-click ve ng-include kullanarak kendi yönlendirmenizi bağlayabilirsiniz (aslında birden fazla seviyeye ihtiyacınız varsa bunu yapmanız gerekir) ng-view, sayfa başına yalnızca bir kez görünebileceğinden). Ayrıca bkz. Stackoverflow.com/questions/12793609/…
Mark Rajcok

2
Hashbang / pushstate / sunucu tarafı oluşturma html kasası için, Twitter biri okumak için çok güzel mühendislik.twitter.com /2012/12/… Bunu nasıl başardıklarını açıklıyor, böylece eski tarayıcı ve arama ile geriye dönük uyumlu motorlar. Angularjs'a özgü olmadığını biliyorum ama akışı tekrarlayabilirsiniz.
jackdbernier

47

Diğerlerinin söylediği gibi html5mode'u etkinleştirdiyseniz .htaccessve aşağıdaki içeriklere sahip bir dosya oluşturduysanız (ihtiyaçlarınıza göre ayarlayın):

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]

Kullanıcılar uygun bir rotaya girdiklerinde uygulamanıza yönlendirilir ve uygulamanız rotayı okuyacak ve içindeki doğru "sayfaya" getirecektir.

DÜZENLEME: Sadece rotalarınızla herhangi bir dosya veya dizin adının çakışmamasına dikkat edin.


bunun bir nginx sürümü var mı? Ben uygulama yüklediğiniz /aboutsürece sayfa yüklediğinizde başarısız olur.
chovy


3
@chovy - İşte nGinx sürümü: server {server_name benim app; kök / yol / uygulama / uygulama; konum / {try_files $ uri $ uri / /index.html; }}
Moin Haidar

4
baş etiketinde <base href = "/"> </base> unutmayın
Silvio Troia

Teşekkürler! bu olmadan, derin bağlantı imkansızdır. Özellikle httpd yapılandırmasına kolay erişemeyeceğiniz bazı bulut / paas ortamlarında derin bağlantıya ihtiyacınız varsa, güzelliğin veya URI'lerin bunu koruma sorununa değdiğinden emin değilim.
Pierre Henry

39

Basit ve kısa görünen cevap yazalım

Sonunda Yönlendirici'ye html5Mode (true) ekleyin ;

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

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

    $locationProvider.html5Mode(true);
})

HTML kafasında taban etiketi ekle

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

@plus'a teşekkürler - yukarıdaki cevabı detaylandırmak için


Bunu çalıştıramadım. Şu konudaki özel bilgilerimle yeni bir soru yayınladım: stackoverflow.com/questions/36041074/… Lütfen buna bakın ve yardımcı olabilirseniz çok memnun olurum.
Larry Martell


12

Aşağıdaki bilgiler şuradan alınmıştır:
https://scotch.io/quick-tips/pretty-urls-in-angularjs-removing-the-hashtag

Temiz URL'leri almak ve hashtag'i URL'den Angular'da kaldırmak çok kolaydır.
Varsayılan olarak, AngularJS URL'leri bir hashtag ile yönlendirir Örneğin:

Yapılması gereken 2 şey var.

  • $ LocationProvider yapılandırılıyor

  • Göreli bağlantılar için tabanımızı ayarlama

  • $ location Hizmet

Açısal'da, $ location hizmeti adres çubuğundaki URL'yi ayrıştırır ve uygulamanızda değişiklikler yapar veya bunun tersi de geçerlidir.

Çok yer hizmet ve ne sağladığı için bir fikir edinmek için resmi Angular $ yer belgeleri okuma tavsiye ediyoruz.

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

$ locationProvider ve html5Mode

  • $ LocationProvider modülünü kullanacağız ve html5Mode öğesini true olarak ayarlayacağız.
  • Açısal uygulamanızı tanımlarken ve rotalarınızı yapılandırırken bunu yapacağız.

    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); });
    

HTML5 Geçmiş API'sı nedir? Bir komut dosyası kullanarak tarayıcı geçmişini değiştirmenin standart bir yoludur. Bu, Açısal'ın sayfayı yenilemeden sayfalarımızın yönlendirme ve URL'lerini değiştirmesini sağlar. Bununla ilgili daha fazla bilgi için iyi bir HTML5 Geçmişi API'sı makalesi:

http://diveintohtml5.info/history.html

Göreli Bağlantıları Ayarlama

  • Göreli bağlantıları kullanarak başvurunuzu etrafında bağlamak için, ayarlamak gerekir <base>içinde <head>belgenizin. Bu, Açısal uygulamanızın kök index.html dosyasında olabilir. <base>Etiketi bulun ve uygulamanız için istediğiniz kök URL'ye ayarlayın.

Örneğin: <base href="https://stackoverflow.com/">

  • Bunu yapılandırmanın birçok yolu vardır ve true olarak ayarlanmış HTML5 modunun göreli bağlantıları otomatik olarak çözmesi gerekir. Uygulamanızın kökü url'den farklıysa (örneğin / tabanım), bunu tabanınız olarak kullanın.

Eski Tarayıcılar için Yedek

  • $ Location hizmeti, HTML5 Geçmiş API'sını desteklemeyen tarayıcılar için otomatik olarak hashbang yöntemine geri döner.
  • Bu sizin için şeffaf bir şekilde gerçekleşir ve çalışması için hiçbir şey yapılandırmanız gerekmez. Açısal $ konum belgelerinden yedek yöntemi ve nasıl çalıştığını görebilirsiniz.

Sonuç olarak

  • Bu, güzel URL'ler almanın ve Açısal uygulamanızdaki hashtag'i kaldırmanın basit bir yoludur. Süper temiz ve süper hızlı Açısal uygulamalar yapmak eğlenin!

3

Bu, Apache ile Angular sunan OS X 10.8'de yerel olarak yapılandırmak istiyorsanız, .htaccess dosyanızda aşağıdakileri yardımcı bulabilirsiniz:

<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>

Ayarlanmadıysa, bağlantılar günlüklerde şu şekilde yasaklanmış bir hata verebilir:

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

Yeniden yazma tabanı gerekir, aksi takdirde, istekleriniz proje kök dizininiz olmayan, yerel olarak varsayılan olarak proje dizininiz olmayan sunucu kökünüze çözümlenecektir; bu nedenle, yolu proje kök dizininizi bulabilecek şekilde ayarlamanız gerekir. Örneğin, makinemde tüm projelerimi sakladığım bir / Users / me / Sites dizinim var. Eski OS X'in kurulumu gibi.

Sonraki iki satır, yolun bir dizin veya dosya olmadığını etkin bir şekilde söyler, bu nedenle uygulama yol yollarınızla aynı dosya veya dizininizin olmadığından emin olmanız gerekir.

Bir sonraki koşul, istek belirtilen dosya uzantılarıyla bitmiyorsa, oraya ihtiyacınız olanı ekleyin

Ve [L] sonuncusu index.html dosyasını sunmayı söylüyor - diğer tüm istekler için uygulamanız.

Hala sorun yaşıyorsanız, apache günlüğünü kontrol edin, muhtemelen size faydalı ipuçları verecektir:

/private/var/log/apache2/error_log

Localhost apache sunucunuz olarak MAMP kullanıyorsanız, ilk RewriteBase öğesinin göreli bir bağlantı olduğundan emin olun. örneğin, RewriteBase / angularjs_site_folder /
David Douglas

3

HTML5 modunu kullanmak için sunucu tarafında URL'nin yeniden yazılması gerekir, temel olarak uygulamanızın giriş noktasına olan tüm bağlantılarınızı yeniden yazmanız gerekir (örn. İndex.html). <base>AngularJS'nin uygulama tabanı olan url kısmı ile uygulama tarafından işlenmesi gereken yol arasında ayrım yapmasına olanak tanıdığından, bu durum için bir etiket gerekmesi de önemlidir. Daha fazla bilgi için bkz. AngularJS Geliştirici Kılavuzu - $ location HTML5 modunu Sunucu Tarafını kullanma .


Güncelleme

Nasıl yapılır: html5Mode ile çalışmak için sunucunuzu yapılandırın 1

Html5Mode'u etkinleştirdiğinizde, #karakter artık URL'lerinizde kullanılmayacaktır. #Hiçbir sunucu tarafı yapılandırma gerektirir çünkü sembol yararlıdır. #Url olmadan çok daha güzel görünüyor, ancak aynı zamanda sunucu tarafı yeniden yazma işlemleri gerektiriyor. İşte bazı örnekler:

Apache Yeniden Yazıyor

<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 Yeniden Yazıyor

server {
    server_name my-app;

    index index.html;

    root /path/to/app;

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

Azure IIS Yeniden Yazıyor

<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>

Ekspres Yeniden Yazmalar

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

Ayrıca bakınız


1

Açısal 6'da yönlendiricinizle şunları kullanabilirsiniz:

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

0

Ana sayfaya (ana sayfa) yönlendirmek için aşağıdaki kodu da kullanabilirsiniz:

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

Yönlendirmenizi yukarıdaki gibi belirledikten sonra, diğer sayfaları yeniden yönlendirebilirsiniz, örneğin:

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

0

**

Angular'da konum stratejisi olarak HTML 5 stilini (PathLocationStrategy) kullanmanız önerilir

** Çünkü

  1. Kullanıcıların anlaması ve hatırlaması daha kolay olan temiz ve SEO Dostu URL'ler üretir.
  2. İstemciyi teslim etmeden önce sunucudaki sayfaları oluşturarak uygulamamızın daha hızlı yüklenmesini sağlayacak olan sunucu tarafı oluşturma işleminden yararlanabilirsiniz.

Hashlocationstrtegy'yi yalnızca eski tarayıcıları desteklemeniz gerekiyorsa kullanın.

Daha fazla bilgi için buraya tıklayın

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.