해시 '#'이없는 AngularJS 라우팅


223

나는 AngularJS를 배우고 있으며 실제로 나를 귀찮게하는 것이 있습니다.

$routeProvider내 응용 프로그램에 대한 라우팅 규칙을 선언 하는 데 사용 합니다.

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

하지만 브라우저에서 내 앱으로 이동하면 app/#/test대신에 표시 됩니다 app/test.

그래서 내 질문은 AngularJS 가이 해시 #를 URL에 추가하는 이유는 무엇 입니까? 피할 가능성이 있습니까?


2
다음은 이 솔루션 이 각도 1.6을 사용하는 경우.
Mistalis

답변:


265

실제로 HTML5가 아닌 브라우저에는 # (해시 태그)가 필요합니다.

그렇지 않으면 언급 된 href에서 서버에 대한 HTTP 호출을 수행합니다. #은 요청을 발생시키지 않는 오래된 브라우저 단락으로 많은 js 프레임 워크가 자체 클라이언트 측 경로 재 지정을 구축 할 수 있습니다.

$locationProvider.html5Mode(true)가능한 경우 각도에 HTML5 전략을 사용 하도록 지시 할 수 있습니다.

HTML5 전략을 지원하는 브라우저 목록은 다음과 같습니다. http://caniuse.com/#feat=history


4
알았어 고마워 이것은 내가 의심 한 것입니다. 그러나 나에게 이것은 꽤 사용자 친화적이지 않습니다! url, app / res를 통해 일부 리소스를 사용할 수 있기를 원합니다. 내 사이트 사용자가 대신 app / # / res를 입력해야한다는 것을 어떻게 알 수 있습니까?
pikkvile

5
그러나 그렇다면 왜 경로가 위치 표시 줄에 표시되어야합니까? 사용자가 사용하지 않으면 단일 페이지 자바 스크립트 응용 프로그램을 만들 수 있습니다.
pikkvile

6
응용 프로그램 상태를 추적하려는 경우에 유용합니다. 프레임 워크는 히스토리 메커니즘을 제공합니다. 또한, 직접 액세스 할 수있는 예를 들어 URL 공유를 통해 응용 프로그램의 상태
플러스 -

6
HTML5 히스토리 API를 지원하는 최신 브라우저에서는 해시 태그가 필요하지 않습니다. @skeep의 답변과 제공된 링크를 참조하십시오. HTML5 모드에서 Angular는 브라우저가 지원하지 않는 경우에만 해시 태그를 사용합니다. 또한 원치 않는 경우 $ routeProvider를 사용할 필요가 없습니다. ng-clicks 및 ng-include를 사용하여 고유 한 라우팅을 연결할 수 있습니다 (실제로 여러 레벨이 필요한 경우이를 수행해야 함) ng-view는 페이지 당 한 번만 나타날 수 있으므로 라우팅) 또한 참조 stackoverflow.com/questions/12793609/...
마크 Rajcok에게

2
hashbang / pushstate / server-side rendering html case의 경우, Twitter는 engineering.twitter.com/2012/12/… 를 읽는 것이 매우 좋습니다. 이전 버전의 브라우저 및 검색과 호환되는 방식을 설명합니다. 엔진. 나는 그것이 angularjs에 국한된 것이 아니라 흐름을 재현 할 수 있다는 것을 알고 있습니다.
jackdbernier

47

다른 사람들이 말한 것처럼 html5mode를 활성화 한 경우 .htaccess다음 내용으로 파일을 만듭니다 (필요에 따라 조정).

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]

사용자는 적절한 경로를 입력하면 앱으로 연결되며, 앱은 경로를 읽고 경로 내에 올바른 "페이지"로 가져옵니다.

편집 : 파일이나 디렉토리 이름이 경로와 충돌하지 않도록하십시오.


이것의 nginx 버전이 있습니까? /about앱을 통해 페이지를 방문하지 않으면 페이지를 로드 할 때 실패합니다.
chovy

그것들을 사용하지는 않았지만 이것을 시도하십시오 : stackoverflow.com/questions/5840497/convert-htaccess-to-nginx
bearfriend

3
@chovy-nGinx 버전으로 이동 : server {server_name my-app; 루트 / path / to / app; 위치 / {try_files $ uri $ uri / /index.html; }}
Moin Haidar

4
기억 <기본 href = "/"> 헤드 태그 </베이스>
실비오 트로이아

감사! 이것이 없으면 딥 링크는 불가능합니다. 딥 링크가 필요한 경우, 특히 일부 클라우드 / 파스 환경에서 httpd 구성에 쉽게 액세스 할 수없는 경우, 예쁘거나 URI가이를 유지하는 데 어려움을 겪을 가치가 있는지 확실하지 않습니다.
Pierre Henry

39

간단하고 짧은 답변을 쓸 수 있습니다

라우터 끝에 끝에 html5Mode (true) 추가하십시오 .

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

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

    $locationProvider.html5Mode(true);
})

HTML 헤드에서 기본 태그 추가

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

위 답변에 대한 자세한 내용은 @plus에게 감사드립니다.


나는 이것을 작동시키지 못했습니다. stackoverflow.com/questions/36041074/ 에서 특정 세부 정보가 포함 된 새 질문을 게시했습니다.이 내용을 살펴보고 도움이 될 수 있으면 크게 감사하겠습니다.
Larry Martell


12

다음 정보가 제공됩니다 :
https://scotch.io/quick-tips/pretty-urls-in-angularjs-removing-the-hashtag

깔끔한 URL을 얻고 Angular의 URL에서 해시 태그를 제거하는 것은 매우 쉽습니다.
기본적으로 AngularJS는 해시 태그로 URL을 라우팅합니다 (예 :

해야 할 두 가지가 있습니다.

  • $ locationProvider 구성

  • 상대 링크를위한 기반 설정

  • $ location 서비스

Angular에서 $ location 서비스는 주소 표시 줄의 URL을 구문 분석하고 응용 프로그램을 변경하거나 그 반대로 변경합니다.

나는 위치 서비스와 그것이 제공하는 것에 대해 느끼기 위해 공식 Angular $ location 문서를 읽는 것이 좋습니다.

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

$ locationProvider 및 html5Mode

  • $ locationProvider 모듈을 사용하고 html5Mode를 true로 설정합니다.
  • Angular 응용 프로그램을 정의하고 경로를 구성 할 때이 작업을 수행합니다.

    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 히스토리 API 란 무엇입니까? 스크립트를 사용하여 브라우저 기록을 조작하는 표준화 된 방법입니다. 그러면 Angular는 페이지를 새로 고치지 않고 페이지의 라우팅 및 URL을 변경할 수 있습니다. 이에 대한 자세한 내용은 다음 HTML5 History API 기사를 참조하십시오.

http://diveintohtml5.info/history.html

상대 링크 설정

  • 상대 링크를 사용하여 응용 프로그램 주위를 링크하려면 문서 <base>에서 를 설정 <head>해야합니다. Angular 앱의 루트 index.html 파일에있을 수 있습니다. <base>태그를 찾아서 앱에 대해 원하는 루트 URL로 설정하십시오.

예를 들면 다음과 같습니다. <base href="https://stackoverflow.com/">

  • 이를 구성하는 다른 많은 방법이 있으며 HTML5 모드를 true로 설정하면 상대 링크가 자동으로 해결됩니다. 응용 프로그램의 루트가 URL과 다른 경우 (예 : / my-base)이를 기본으로 사용하십시오.

이전 브라우저를위한 대체

  • $ location 서비스는 HTML5 History API를 지원하지 않는 브라우저의 경우 자동으로 hashbang 메소드로 대체됩니다.
  • 이것은 투명하게 발생하며 작동하도록 아무것도 구성 할 필요가 없습니다. Angular $ location 문서에서 대체 방법과 작동 방식을 볼 수 있습니다.

결론적으로

  • 이것은 예쁜 URL을 얻고 Angular 응용 프로그램에서 해시 태그를 제거하는 간단한 방법입니다. 매우 깨끗하고 빠른 앵귤러 앱을 만들어보세요!

3

Apache와 함께 Angular를 제공하는 OS X 10.8에서 로컬로 이것을 구성하려면 .htaccess 파일 도움말에서 다음을 찾을 수 있습니다.

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

옵션 + FollowSymlinks를 설정하지 않으면 다음과 같이 로그에 금지 된 오류가 발생할 수 있습니다.

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

다시 쓰기 기본이 필요합니다. 그렇지 않으면 호스트를 특별히 구성하지 않은 경우 요청이 프로젝트 루트가 아닌 로컬 서버 로컬로 요청이 해결되므로 요청이 프로젝트 루트 디렉토리를 찾을 수 있도록 경로를 설정해야합니다. 예를 들어 내 컴퓨터에는 모든 프로젝트를 유지하는 / Users / me / Sites 디렉토리가 있습니다. 이전 OS X 설정처럼.

다음 두 줄은 경로가 디렉토리 또는 파일이 아닌지 효과적으로 말하므로 앱 경로 경로와 동일한 파일이나 디렉토리가 없는지 확인해야합니다.

다음 조건은 요청이 파일 확장자로 끝나지 않는 경우 메시지를 표시하므로 필요한 것을 추가하십시오.

마지막으로 [L]은 index.html 파일 (다른 모든 요청에 ​​대한 앱)을 제공한다고 말하고 있습니다.

여전히 문제가 발생하면 아파치 로그를 확인하면 유용한 힌트를 얻을 수 있습니다.

/private/var/log/apache2/error_log

로컬 호스트 아파치 서버로 MAMP를 사용하는 경우 첫 번째 RewriteBase가 상대 링크인지 확인하십시오. 예 : RewriteBase / angularjs_site_folder /
David Douglas

3

HTML5 모드를 사용하려면 서버 측에서 URL을 다시 작성해야합니다. 기본적으로 모든 링크를 응용 프로그램의 진입 점 (예 : index.html)에 다시 작성해야합니다. <base>이 경우에는 AngularJS가 응용 프로그램 기반 URL 부분과 응용 프로그램에서 처리해야하는 경로를 구별 할 수 있으므로 태그가 필요합니다 . 자세한 내용은 AngularJS 개발자 안내서-$ location HTML5 모드 서버 측 사용을 참조하십시오 .


최신 정보

방법 : html5Mode와 작동하도록 서버 구성 1

html5Mode를 사용하도록 설정하면 해당 #문자가 더 이상 URL에 사용되지 않습니다. 이 #기호는 서버 측 구성이 필요하지 않기 때문에 유용합니다. 이 없으면 #URL이 훨씬 멋지게 보이지만 서버 측 다시 쓰기도 필요합니다. 여기 몇 가지 예가 있어요.

아파치 다시 작성

<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 재 작성

server {
    server_name my-app;

    index index.html;

    root /path/to/app;

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

Azure IIS 다시 쓰기

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

빠른 다시 쓰기

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

또한보십시오


1

Angular 6에서는 라우터와 함께 다음을 사용할 수 있습니다.

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

0

아래 코드를 사용하여 기본 페이지 (홈)로 리디렉션 할 수도 있습니다.

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

위와 같이 리디렉션을 지정한 후 다른 페이지를 리디렉션 할 수 있습니다 (예 :

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

0

**

Angular에서는 HTML 5 스타일 (PathLocationStrategy)을 위치 전략으로 사용하는 것이 좋습니다.

** 때문에

  1. 사용자가 이해하고 기억하기 쉬운 깨끗하고 SEO 친화적 인 URL을 생성합니다.
  2. 서버 측 렌더링을 활용하면 클라이언트에 페이지를 제공하기 전에 서버에서 페이지를 먼저 렌더링하여 애플리케이션로드 속도를 높일 수 있습니다.

이전 브라우저를 지원해야하는 경우에만 Hashlocationstrtegy를 사용하십시오.

자세한 내용을 보려면 여기를 클릭하십시오

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.