原文:http://blog.fens.me/angularjs-url/html
AngularJS體驗式編程系列文章,將介紹如何用angularjs構建一個強大的web前端系統。angularjs是由Google團隊開發的一款很是優秀web前端框架。在當前如此多的web框架下,angularjs能脫穎而出,從架構設計上就高人一等,雙向數據綁定,依賴注入,指令,MVC,模板。Angular.js創新地把後臺技術融入前端開發,掃去jQuery一度的光芒。用angularjs就像寫後臺代碼,更規範,更結構化,更可控。前端
關於做者html5
前言nginx
每天都在用AngularJS,各種文檔也都看過好幾遍,但老是些編程上的事找不到優雅的解決辦法。今天終於把AngularJS的項目訪問路徑URL裏的#號去掉了,這個問題不見得有多難,關鍵是花多長時間去理解AngularJS框架自己。程序員
目錄angularjs
使用AngularJS的朋友都應該瞭解,AngularJS框架定義了本身的前端路由控制器,經過不一樣URL實現單面(ng-app)對視圖(ng-view)的部署刷新,並支持HTML5的歷史記錄功能,詳細介紹能夠參考文章:AngularJS路由和模板。web
對於默認的狀況,是不啓動HTML5模式的,URL中會包括一個#號,用來區別是AngularJS管理的路徑仍是WebServer管理的路徑。編程
好比:下面的帶#號的URL,是AngularJS管理的路徑。api
這種體驗實際上是不太友好的,特別是像我這種喜歡簡潔設計的人,#號的出現非我自願的,怎麼看怎麼難受。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/book) ,就會出現404錯誤。
就是這個問題糾結了我好長時間,讓我不得不用帶#號的URL。
那麼,這個問題的緣由出在哪裏了呢? 在路徑解析上出錯了。
讓我從頭提及,AngularJS是單頁應用,一個ng-app對應一個頁面,一個URL。AngularJS實現了本身的前端路由,讓一個ng-app能夠管理多個URL,再對應到多個ng-vew上面。當咱們去訪問URL(http://onbook.me/book) 的時候,怎麼肯定這個路徑是 WebServer 後臺管理的URL仍是AngularJS前臺管理的URL呢?
分2種狀況看:
若是能把這層想明白,技術上就很是容易解決了。咱們讓WebServer把屬於AngularJS管理的路由URL,都發轉到ng-app就能夠解決404的問題了,同時,沒有#號,還支持HTML5的歷史記錄查詢!!
實現起來分爲2種解決方案:
靜態網站,咱們須要修改的地方包括3個文件
編輯 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; } }
這樣,靜態網站就搞定了,沒有麻煩的#號了,能夠直接訪問和任意頁面的刷新。
動態網站,咱們一樣須要修改的地方包括3個文件。
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的各類無解的問題,仍是值得的。優秀的框架值得咱們的研究和使用,在摸索中前進!