AngularJS URL에서 조각 식별자 제거 (# 기호)


257

angular.js URL에서 # 기호를 제거 할 수 있습니까?

뷰를 변경하고 매개 변수로 URL을 업데이트 할 때 브라우저의 뒤로 버튼 등을 계속 사용할 수 있기를 원하지만 # 기호는 원하지 않습니다.

튜토리얼 routeProvider는 다음과 같이 선언됩니다.

angular.module('phonecat', []).
  config(['$routeProvider', function($routeProvider) {
  $routeProvider.
  when('/phones', {templateUrl: 'partials/phone-list.html',   controller: PhoneListCtrl}).
  when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
  otherwise({redirectTo: '/phones'});
}]);

#없이 동일한 기능을 갖도록 이것을 편집 할 수 있습니까?


13
hashtag nice one
BoJack Horseman


나에게 여기의 모든 대답이 잘못되었습니다. URL을 "다시 작성"하고 #를 제거 할 수 있지만 #없이 웹 페이지에 직접 액세스 할 수는 없습니다. 여기에 어떤 실제 솔루션?
amdev

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

답변:


251

예, 구성해야합니다 $locationProvider및 설정 html5Modetrue:

angular.module('phonecat', []).
  config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {

    $routeProvider.
      when('/phones', {templateUrl: 'partials/phone-list.html',   controller: PhoneListCtrl}).
      when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}).
      otherwise({redirectTo: '/phones'});

    $locationProvider.html5Mode(true);

  }]);

10
IE lt 10 은 설정하여 활성화 된 html5 기록 API를 지원하지 않기 때문에 html5Mode(true). IE에서는 #경로 에서 사용해야 합니다.
Maxim Grach

10
@powtac IE lt 10은 Internet Explorer가 10보다 낮은 버전을 의미합니다.
Maxim Grach

6
IE에서 #을 사용하도록 대체 할 수 있습니까? 그냥 포장 한 간단하게인가 $locationProvider.html5Mode(true);if !(IE lt 10)?
Andy Hayden

52
따라서이 솔루션은 URL에 해시 태그가있는 경우 URL에서 해시 태그를 제거하는 것을 해결하지만 해시 태그를 먼저 포함시키지 않으려는 요청에 응답하는 방법은 해결하지 못합니다. 일명, 그것은 blah / # / phones- > blah / phones를 해결 하지만 blah / phones를 직접 처리하지는 않습니다 .
Luke

9
index.html <head> 섹션에 <base href = "/"/>를 넣어야했습니다.
nyxz

55

html5 히스토리 API에 대한 브라우저 지원을 확인하십시오.

  if(window.history && window.history.pushState){
    $locationProvider.html5Mode(true);
  }

23
이것은 질문에 직접 대답하지 않으므로 주석으로 더 적합 할 수 있습니다.
brandonscript

31
개발자 안내서 에 따르면 이 탐지는 자동으로 수행됩니다.If the HTML5 History API is not supported by a browser, the $location service will fall back to using the hashbang URLs automatically
IanB

매력처럼 작동했으며 브라우저 버전 확인보다는 미래의 방법 인 방법 확인에 감사합니다.
셰인

46

예쁜 URL축소 후 코드가 작동 하도록 해시 태그를 제거하려면 아래 예제와 같이 코드를 구성해야합니다.

jobApp.config(['$routeProvider','$locationProvider',
    function($routeProvider, $locationProvider) {
        $routeProvider.
            when('/', {
                templateUrl: 'views/job-list.html',
                controller: 'JobListController'
            }).
            when('/menus', {
                templateUrl: 'views/job-list.html',
                controller: 'JobListController'
            }).
            when('/menus/:id', {
                templateUrl: 'views/job-detail.html',
                controller: 'JobDetailController'
            });

         //you can include a fallback by  including .otherwise({
          //redirectTo: '/jobs'
        //});


        //check browser support
        if(window.history && window.history.pushState){
            //$locationProvider.html5Mode(true); will cause an error $location in HTML5 mode requires a  tag to be present! Unless you set baseUrl tag after head tag like so: <head> <base href="https://stackoverflow.com/">

         // to know more about setting base URL visit: https://docs.angularjs.org/error/$location/nobase

         // if you don't wish to set base URL then use this
         $locationProvider.html5Mode({
                 enabled: true,
                 requireBase: false
          });
        }
    }]);

15
내용은 requireBase: false
whoan

2
안녕하세요 @digitlimit, $locationProvider.html5Mode코드를 추가 한 후 코드 $urlRouterProvider.otherwise('/home');작동이 중지되었습니다.
Jaikrat

18

$locationProvider.html5Mode(true)설정된 후 web.config에 규칙을 작성합니다.app.js .

희망은 누군가를 도와줍니다.

  <system.webServer>
    <rewrite>
      <rules>
        <rule name="AngularJS" stopProcessing="true">
          <match url=".*" />
          <conditions logicalGrouping="MatchAll">
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
            <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
          </conditions>
          <action type="Rewrite" url="/" />
        </rule>
      </rules>
    </rewrite>
  </system.webServer>

내 index.html에서 이것을 추가했습니다. <head>

<base href="/">

서버에 iis 용 URL Rewriter를 설치하는 것을 잊지 마십시오.

또한 Web Api 및 IIS를 사용하는 경우이 일치 URL은 API 호출을 변경하므로 작동하지 않습니다. 따라서 세 번째 입력 (세 번째 조건 줄)을 추가하고 호출을 제외시키는 패턴을 제공하십시오.www.yourdomain.com/api


1
IIS 용 URL Rewriter를 어떻게 설치합니까? Azure에서 호스팅하고 있습니다.
Prabhu

11

AngularJS가있는 MVC가있는 .NET 스택에있는 경우 URL에서 '#'을 제거하려면 다음과 같이해야합니다.

  1. _Layout 페이지에서 기본 href를 설정하십시오. <head> <base href="https://stackoverflow.com/"> </head>

  2. 그런 다음 각도 앱 구성에 다음을 추가하십시오. $locationProvider.html5Mode(true)

  3. 위의 URL에서 '#'을 제거하지만 "yoursite.com/about"에있는 경우 페이지 새로 고침이 작동하지 않습니다. 예를 들어 refreash는 404를 제공합니다. 이는 MVC가 각도 라우팅과 MVC 패턴에 대해 알지 못하기 때문입니다. MVC 라우팅 경로에없는 'about'에 대한 MVC 페이지를 찾습니다. 이에 대한 해결 방법은 모든 MVC 페이지 요청을 단일 MVC보기로 전송하는 것입니다.

URL :

routes.MapRoute(
    name: "App",
    url: "{*url}",
    defaults: new {
        controller = "Home", action = "Index"
    }
);

어느 파일을 라우트를 추가해야합니까?
Vicheanak

1
RouteConfig.cs의 App_Start 폴더 아래
Maksood

5

html5mode를 조정할 수는 있지만 페이지의 html 앵커에 포함 된 링크 및 브라우저 주소 표시 줄에서 URL의 모양에 대해서만 작동합니다. 페이지 외부에서 해시 태그없이 (html5mode의 유무에 관계없이) 서브 페이지를 요청하면 404 오류가 발생합니다. 예를 들어, 다음 CURL 요청은 html5mode와 상관없이 페이지를 찾을 수 없음 오류를 발생시킵니다.

$ curl http://foo.bar/phones

다음은 루트 / 홈 페이지를 반환하지만

$ curl http://foo.bar/#/phones

그 이유는 요청이 서버에 도착하기 전에 해시 태그 이후의 항목이 제거되기 때문입니다. 따라서에 대한 요청은에 대한 요청으로 http://foo.bar/#/portfolio서버 에 도착합니다 http://foo.bar. 서버는 (아마도) 200 OK 응답으로 응답 http://foo.bar하고 에이전트 / 클라이언트는 나머지를 처리합니다.

따라서 다른 사람과 URL을 공유하려는 경우 해시 태그를 포함 할 수 밖에 없습니다.


이 주위에 방법이 없습니까? 이것은 꽤 큰 문제입니다.
user441521

5

2 단계-1 단계를 수행
하십시오. 먼저 앱 구성 파일에서 $ locationProvider.html5Mode (true) 를 설정하십시오.
예를 들어-
angular.module('test', ['ui.router']) .config(function($stateProvider, $urlRouterProvider, $locationProvider) { $locationProvider.html5Mode(true); $urlRouterProvider.otherwise('/'); });

2. 메인 페이지 에서 <base>를 두 번째로 설정합니다 .
예를 들어->
<base href="https://stackoverflow.com/">

$ location 서비스는 HTML5 히스토리 API를 지원하지 않는 브라우저의 해시 파트 메소드로 자동 대체됩니다.


3

내 솔루션은 .htaccess를 만들고 #Sorian 코드를 사용하는 것입니다. .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]

1

설명서에 따르면. 당신이 사용할 수있는:

$locationProvider.html5Mode(true).hashPrefix('!');

주의 : 브라우저가 HTML 5를 지원하지 않으면 걱정하지 마십시오. D는 hashbang 모드로 대체됩니다. 따라서 if(window.history && window.history.pushState){ ... }수동으로 확인할 필요가 없습니다

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

HTML5 브라우저에서 : 각도는 자동으로 리디렉션됩니다.example.com/other

HTML5 브라우저 아님 : 각도가 자동으로 리디렉션됩니다.example.com/#!/other


1

이 답변은 nginx를 리버스 프록시로 사용하고 있으며 $ locationProvider.html5mode를 true로 이미 설정했다고 가정합니다.

-> 위의 모든 멋진 것들로 여전히 어려움을 겪고있는 사람들을 위해.

분명히 @maxim grach 솔루션은 잘 작동하지만 해시 태그를 처음에 포함하지 않으려는 요청에 응답하는 방법에 대한 솔루션은 PHP가 404를 보내고 있는지 확인한 다음 URL을 다시 작성하는 것입니다. 다음은 nginx 코드입니다.

PHP 위치에서 404 PHP 오류를 감지하고 다른 위치로 리디렉션하십시오.

location ~ \.php${
  ...
  fastcgi_intercept_errors on;
  error_page 404 = /redirect/$request_uri ;
}

그런 다음 리디렉션 위치에 url을 다시 쓰고 데이터를 proxy_pass하여 오프 사이트로 내 웹 사이트 URL을 내 블로그 URL 위치에 놓으십시오. (신청 : 시도한 후에 만 ​​질문)

location /redirect {
  rewrite ^/redirect/(.*) /$1;
  proxy_pass http://www.techromance.com;
}

그리고 마술을보십시오.

그리고 그것은 나를 위해 적어도 작동합니다.


이것을 어디에 추가합니까?
Volatil3

위의 코드를 어디에 추가합니까? 메인 Nginx 설정 파일에 넣으십시오.
Satys

1

시작 모든 index.html을 삭제에서 #에서 <a href="#/aboutus">About Us</a>이 같이해야한다, 그래서 <a href="https://stackoverflow.com/aboutus">About Us</a>index.html을 쓰기 헤드 태그에 부탁해 <base href="https://stackoverflow.com/">바로 지난 후 메타 태그 .

이제 라우팅 js에 다음 과 같은 것을 주입 $locationProvider하고 작성하십시오 $locatonProvider.html5Mode(true);.

app.config(function ($routeProvider, $locationProvider) {
    $routeProvider
        .when("/home", {
            templateUrl: "Templates/home.html",
            controller: "homeController"
        })
            .when("/aboutus",{templateUrl:"Templates/aboutus.html"})
            .when("/courses", {
                templateUrl: "Templates/courses.html",
                controller: "coursesController"
            })
            .when("/students", {
                templateUrl: "Templates/students.html",
                controller: "studentsController"
            })
        $locationProvider.html5Mode(true);
    });

자세한 내용은이 비디오를 참조하십시오 https://www.youtube.com/watch?v=XsRugDQaGOo


모든 # Url을 제거하면 #urls를 제거하지 않고 테스트했기 때문에 도움이되었습니다.
optimistanoop

1

이것은 이것에 대해 상당히 늦었다 고 생각합니다. 그러나 아래 구성을 app.module 가져 오기에 추가하면 작업이 수행됩니다.

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

0

1 단계 : $ locationProvider 서비스를 앱 구성 생성자에 주입

2 단계 : 앱 구성 생성자에 $ locationProvider.html5Mode (true) 코드 행을 추가합니다.

3 단계 : 컨테이너 (랜딩, 마스터 또는 레이아웃) 페이지에서 html 태그 (예 : <base href="https://stackoverflow.com/"> 내부 합니다.

4 단계 : 모든 앵커 태그에서 구성을 라우팅하기 위해 모든 '#'제거 예를 들어 href = "# home"은 href = "home"; href = "# about"은 herf = "about"; href = "# contact "는 href ="contact "가됩니다.

 <ul class="nav navbar-nav">
     <li><a href="home">Home</a></li>
     <li><a href="about">About us</a></li>
     <li><a href="contact">Contact us</a></li>
</ul>

-1

다만 추가 $locationProvider에를

.config(function ($routeProvider,$locationProvider)

다음 추가 $locationProvider.hashPrefix('');

.otherwise({
        redirectTo: '/'
      });

그게 다야.

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