【轉】AngularJS去掉的URL裏的#號

原文:http://blog.fens.me/angularjs-url/html

AngularJS去掉的URL裏的#號

AngularJS體驗式編程系列文章,將介紹如何用angularjs構建一個強大的web前端系統。angularjs是由Google團隊開發的一款很是優秀web前端框架。在當前如此多的web框架下,angularjs能脫穎而出,從架構設計上就高人一等,雙向數據綁定,依賴注入,指令,MVC,模板。Angular.js創新地把後臺技術融入前端開發,掃去jQuery一度的光芒。用angularjs就像寫後臺代碼,更規範,更結構化,更可控。前端

關於做者html5

  • 張丹(Conan), 程序員Java,R,PHP,Javascript
  • weibo:@Conan_Z
  • blog: http://blog.fens.me
  • email: bsspirit@gmail.com

angularjs-url

前言nginx

每天都在用AngularJS,各種文檔也都看過好幾遍,但老是些編程上的事找不到優雅的解決辦法。今天終於把AngularJS的項目訪問路徑URL裏的#號去掉了,這個問題不見得有多難,關鍵是花多長時間去理解AngularJS框架自己。程序員

目錄angularjs

  1. URL的#號問題
  2. 找到錯誤緣由
  3. 靜態網站的解決方案
  4. 動態網站的解決方案

1. URL的#號問題

使用AngularJS的朋友都應該瞭解,AngularJS框架定義了本身的前端路由控制器,經過不一樣URL實現單面(ng-app)對視圖(ng-view)的部署刷新,並支持HTML5的歷史記錄功能,詳細介紹能夠參考文章:AngularJS路由和模板web

對於默認的狀況,是不啓動HTML5模式的,URL中會包括一個#號,用來區別是AngularJS管理的路徑仍是WebServer管理的路徑。編程

好比:下面的帶#號的URL,是AngularJS管理的路徑。api

  • http://onbook.me/
  • http://onbook.me/#/
  • http://onbook.me/#/book
  • http://onbook.me/#/about

這種體驗實際上是不太友好的,特別是像我這種喜歡簡潔設計的人,#號的出現非我自願的,怎麼看怎麼難受。AngularJS框架提供了一種HTML5模式的路由,能夠直接去掉#號。前端框架

經過設置$locationProvider.html5Mode(true)就好了。

book.config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {

   //..省略代碼
    $locationProvider.html5Mode(true);
}]);

支持HTML5的路由URL。

  • http://onbook.me/
  • http://onbook.me/book
  • http://onbook.me/about

接下來的問題就來了,當用這種方式設置了路徑之後。若是用戶從首頁(http://onbook.me/)開始訪問,而後跳轉到 圖書頁(http://onbook.me/book)一切正常。但若是用戶直接打開 圖書頁(http://onbook.me/book) ,就會出現404錯誤。

url1

就是這個問題糾結了我好長時間,讓我不得不用帶#號的URL。

2. 找到錯誤緣由

那麼,這個問題的緣由出在哪裏了呢? 在路徑解析上出錯了。

讓我從頭提及,AngularJS是單頁應用,一個ng-app對應一個頁面,一個URL。AngularJS實現了本身的前端路由,讓一個ng-app能夠管理多個URL,再對應到多個ng-vew上面。當咱們去訪問URL(http://onbook.me/book) 的時候,怎麼肯定這個路徑是 WebServer 後臺管理的URL仍是AngularJS前臺管理的URL呢?

分2種狀況看:

  • 1. 用戶若是是先訪問 首頁(http://onbook.me),而後再跳轉到 頁面(http://onbook.me/book),則這個跳轉是由AngularJS前臺管理的URL,訪問是正常的。
  • 2. 用戶直接訪問 頁面(http://onbook.me/book)時,請求是先被提交到了WebServer後臺,後臺路由沒有對應頁面(http://onbook.me/book)的路由管理,就會出現404的錯誤。

若是能把這層想明白,技術上就很是容易解決了。咱們讓WebServer把屬於AngularJS管理的路由URL,都發轉到ng-app就能夠解決404的問題了,同時,沒有#號,還支持HTML5的歷史記錄查詢!!

實現起來分爲2種解決方案:

  • 1. 靜態網站:純前臺網站(JS+HTML+CSS),經過Nginx提供Web服務。
  • 2. 動態網站:前臺(JS + HTML + CSS) + 後臺Node.js提供Web服務。

3. 靜態網站的解決方案

靜態網站,咱們須要修改的地方包括3個文件

  • index.html : ng-app的定義文件
  • app.js : 對應ng-app的控制文件
  • nginx.conf : nginx的網站配置文件

編輯 index.html,增長base標籤。

<html lang="zh-CN" ng-app="book">
<head>
    <base href="/">
	
// 省略代碼
</head>

編輯app.js,增長 $locationProvider.html5Mode(true);

book.config(['$routeProvider', '$locationProvider', '$sceProvider', 'tplProvider', function ($routeProvider, $locationProvider, $sceProvider, tplProvider) {
    $routeProvider
        .when('/', {templateUrl: tplProvider.html('welcome'), controller: 'WelcomeCtrl'})
        .when('/book', {templateUrl: tplProvider.html('book'), controller: 'BookCtrl'})             //圖書
        .when('/book-r1', {templateUrl: tplProvider.html('book-r1'), controller: 'BookR1Ctrl'})   //R的極客理想
        .when('/video', {templateUrl: tplProvider.html('video'), controller: 'VideoCtrl'})         //視頻
        .when('/about', {templateUrl: tplProvider.html('about'), controller: 'AboutCtrl'})         //關於做者
        .otherwise({redirectTo: '/'});
    $locationProvider.html5Mode(true);
}]);

編輯nginx的配置文件,增長try_files配置。

server {
        set $htdocs /www/deploy/mysite/onbook;
        listen 80;
        server_name onbook.me;
        location / {
            root $htdocs;
            try_files $uri $uri/ /index.html =404;
        }
}

這樣,靜態網站就搞定了,沒有麻煩的#號了,能夠直接訪問和任意頁面的刷新。

4. 動態網站的解決方案

動態網站,咱們一樣須要修改的地方包括3個文件。

  • index.html : ng-app的定義文件
  • app.js : 對應ng-app的控制文件
  • server.js : Express框架的路由訪問控制文件

index.html 和 app.js兩個文件修改,同靜態網站的解決方案。動態網站,通常不是經過Nginx直接路由,而是經過Web服務器管理路由。假設咱們使用的是Node.js的Express的Web框架。

打開Express框架的路由訪問控制文件server.js,增長路由配置。

app.use(function (req, res) {
    console.log(req.path);
    if(req.path.indexOf('/api')>=0){
        res.send("server text");

    }else{ //angular啓動頁
        res.sendfile('app/index.html');
    }
});

設置當 站內路徑(req.path) 不包括 /api 時,都轉發到 AngularJS的ng-app(index.html)。因此,咱們再直接訪問地址 (http://onbook.me/book)時,/book 不包括 /api,就會被直接轉發到AngularJS進行路由管理。咱們就實現了路由的優化!

我已用了AngularJS有8-9個月了,主要功能都用到了,但還不見其全貌。常常會遇到各類問題,不過比起jQuery的各類無解的問題,仍是值得的。優秀的框架值得咱們的研究和使用,在摸索中前進!

相關文章
相關標籤/搜索