url 中存在#號(hào)
第六講的時(shí)候我說過了,angular是通過瀏覽器地址欄的url(http://www.xxx.com/#/index
)號(hào)后面的部分#/index
來確定當(dāng)前用戶訪問的是哪個(gè)頁面,然后根據(jù)這個(gè)URL對(duì)視圖(ng-view)完成更新;并支持HTML5的歷史記錄功能。
- angular的地址欄是什么樣子?
http://www.xxx.com/
http://www.xxx.com/#/login
http://www.xxx.com/#/index
http://www.xxx.com/#/regsiter
- 這跟我們平常見到的鏈接不一樣(如
http://www.xxx.com/admin/login
),這樣就區(qū)分了這個(gè)路由是由angular
管理的還是由webserver
管理的。
總有強(qiáng)迫癥患者想要去掉這個(gè) # 號(hào),那么angular可以去掉這個(gè)#號(hào)嗎? 當(dāng)然可以!!!!
- angular 提供了一個(gè)
HTML5模式
,啟動(dòng)這個(gè)路由模式就可以去掉路由中的 # 號(hào) (即在配置路由時(shí),注入$locationProvider
服務(wù),路由配置中加入如下代碼$locationProvider.html5Mode(true);
)
var appH5 = angular.module('appH5', ['ngRoute']);
// 配置路由
appH5.config(['$routeProvider','$locationProvider',function($routeProvider,$locationProvider) {
$routeProvider.otherwise({redirectTo: '/index'});
$routeProvider
.when('/index', {
templateUrl: "views/index.html",
controller:'indexCtrl'
})
.when('/regsiter', {
templateUrl: "views/regsiter.html",
controller:'regsiterCtrl'
})
.when('/message/:msgid', {
templateUrl: "views/message.html",
controller:'messageCtrl'
});
$locationProvider.html5Mode(true);//啟用html5模式
}])
- 做完以上的操作,我們就可以優(yōu)雅的訪問URL了???
http://www.xxx.com/#/login => http://www.xxx.com/login
嘗試了之后發(fā)現(xiàn),當(dāng)我們直接打開 http://www.xxx.com/
路由中配置默認(rèn)重置到 /index$routeProvider.otherwise({redirectTo: '/index'});
;沒有問題,我們?cè)陧撁嬷悬c(diǎn)擊鏈接和通過$location.path()跳轉(zhuǎn)也沒有問題,但是當(dāng)我們直接在地址欄輸入 http://www.xxx.com/index
;然后你會(huì)看見下邊的情況
問題原因
剛剛說過,http://www.xxx.com/#/regsiter
和 http://www.xxx.com/admin/login
這兩個(gè)url用 # 區(qū)分了是angular
還是webserver
管理的url,當(dāng)我們直接訪問 http://www.xxx.com/login
沒有#號(hào) ,這個(gè)時(shí)候 webserver就嘗試去解析,發(fā)現(xiàn)找不到對(duì)應(yīng)的url,這個(gè)時(shí)候自然就拋出 404。
找到問題,既然問題出在webserver解析不了,那我們何不把webserver解析不了的url都轉(zhuǎn)發(fā)到angular應(yīng)用里面?這不就皆大歡喜了
解決辦法 本人開發(fā)用的服務(wù)器是 nginx+js+html+css 前后端分離的方式
1、修改SPA主入口 index.html(加入<base href="/">
)
<!doctype html>
<html ng-app="appH5">
<head>
<base href="/">
</head>
<body >
</body>
</html>
2、開啟html5模式
var appH5 = angular.module('appH5', ['ngRoute']);
// 配置路由
appH5.config(['$routeProvider','$locationProvider',function($routeProvider,$locationProvider) {
$routeProvider.otherwise({redirectTo: '/index'});
$routeProvider
.when('/index', {
templateUrl: "views/index.html",
controller:'indexCtrl'
})
.when('/regsiter', {
templateUrl: "views/regsiter.html",
controller:'regsiterCtrl'
})
.when('/message/:msgid', {
templateUrl: "views/message.html",
controller:'messageCtrl'
});
$locationProvider.html5Mode(true);//啟用html5模式
}])
3、配置nginx服務(wù)器(nginx-1.11.0/conf/nginx.conf)
server {
listen 8088;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root C:\Git\app\router_demo;
try_files $uri $uri/ /index.html =404;
}
}
其他服務(wù)器(本人不用這些服務(wù)器,未經(jīng)過驗(yàn)證,只做參考)
Apache的設(shè)置【.htaccess的寫法】
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ – [L]
# If the requested pattern is file and file doesn’t exist, send 404
RewriteCond %{REQUEST_URI} ^(/[a-z_-s0-9.]+)+.[a-zA-Z]{2,4}$
RewriteRule ^ – [L,R=404]
# otherwise use history router
RewriteRule ^ /index.html