1. 程式人生 > >Angular2+如何去除url中的#

Angular2+如何去除url中的#

當前 oot chan wirte 內容 init.d 1.9 .so 執行命令

最近,接到反饋說百度統計無法對#號後的URL進行分析,需要前端這邊去掉URL中的#,下面我分享一下這個問題的處理過程。

1、Angular2+ 路由策略

1.1 HashLocationStragegy

通過hash實現,當url的hash發生改變時,觸發hashchange註冊的回調(低版本的瀏覽器沒有hashchange事件,通過輪回檢測url實現),回調中去進行不同的操作,進行不同的內容展示。使用hash來實現的話,URI規則中要帶上#,路由中#後邊的內容就是hash,而我們常說的錨點嚴格來說應該是頁面中的a[name]等元素。url格式如下:

http://121.201.95.249/#/home

適用於基於錨點標記的路徑,比如/#/concat,/#/about,後端只需要配置一個根路由即可。

1.2 PathLocationStrategy

通過history實現,angular2的默認策略,也就是HTML5路由,使用這個路由的常規路徑就是/concat,/about,不帶#。url格式如下:

http:// 121.201.95.249/home

這種策略需要後臺配置支持,因為我們的應用是單頁面應用,如果後臺沒有正確的配置,當用戶在瀏覽器從http: // 121.201.95.249/concat跳轉到http: // 121.201.95.249/about或者刷新時就會返回404,需要在服務端裏面覆蓋所有的路由情況(後端可以通過nginx或者apache等配置)。

2、如何去除

主要分兩部分,前端路由策略模式修改,以及後端服務器配置。我的項目中後端服務器用的是Apache,下面我將以這個為例子進行解析。

2.1 前端修改

index.html文件:
在head裏設置base-href,如果沒有設置,當通過“深鏈接”進入該應用時,瀏覽器就不能正確的加載網站資源(圖片、CSS、腳本)。如下:

<base href="/">

base-href,主要是設置你的項目訪問的根目錄,如果你的項目是放在服務器某一文件夾裏面的,比如通過http: // 121.201.95.249/myApp/home才訪問到你的項目,那麽根目錄設置如下:

<base href="/myApp/">

app.module.ts文件:
import { ROUTER_CONFIG } from './app.routes.ts';
@NgModule({
 imports: [
 ...
 RouterModule.forRoot(routes) 
 // RouterModule.forRoot(routes, { useHash: true } ) 這樣寫是帶#的
 ], 
})

app.routes.ts文件:
import { NgModule } from '@angular/core';
import { Routes } from '@angular/router';
export const routes: Routes = [
 {
 ...
 }
];

設置到這裏便可以實現去掉“#”跳轉了,但是每次刷新或者直接輸鏈接進到頁面時會報錯提示:404找不到頁面。因此,我們需要後端配合做路由重定向。

2.2 後端服務器配置

Apache配置文件修改:


RewriteEngine On
# 如果請求的是現有資源,則按原樣執行
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# 如果請求的資源不存在,則使用index.html
RewriteRule ^ /index.html

Apache Rewrite配置就是用來設置重定向的,上面5行(不包括#的註釋內容)配置內容的意思是:

第一行: 將RewriteEngine引擎設置為on,就是讓url重寫生效,用於開啟rewrite功能;
第二行: RewriteCond是指令定義了一個規則的條件,即在一個RewriteRule指令之前有一個或多個RewriteCond指令。 條件之後的重寫規則(RewirteRule)僅在當前URI與pattern匹配並且符合這些條件的時候才會起作用。上面的匹配規則意思是,如果文件存在,就直接訪問文件,執行第四行重寫規則(RewirteRule)停止分析,否則執行第三行
第三行: 如果目錄存在就直接訪問目錄,然後執行第四行重寫規則(RewirteRule)停止分析
第四行: 表明當前規則是最後一條規則,停止分析後面的規則
第五行: 意思是把請求發送到index.html;當第二第三條規則都不滿足的時候,就不執行第四行的RewriteRule,直接執行第五行的RewriteRule,把請求發送到index.html,實現重定向

想對規則進行更多了解,請查看這篇文章(https://www.jb51.net/article/82158.htm) ,下面我說一下Apache的配置步驟。
大家如果是在集成環境比如uwamp,wamp或者Apache1可以打開配置文件httpd.conf,如果是Apache2則打開配置文件/etc/apache2/apache2.conf,進行修改。
(1) 引入重寫rewrite模塊
如果是集成環境或者Apache1,找到#LoadModule rewrite_module modules/mod_rewrite.so,去掉前面的”#”:

LoadModule rewrite_module modules/mod_rewrite.so

如果是Apache2的話,執行命令加載Rewrite模塊:

a2enmod rewrite

執行後,會提示OK和重啟Apache命令(/etc/init.d/apache2 restart)。

(2)添加配置規則

<VirtualHost *:80>
    ServerName myApp
    DocumentRoot /www/myApp
    <Directory /www/myApp>
        RewriteEngine on
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d 
        RewriteRule ^ - [L]
        RewriteRule ^ index.html [L]
    </Directory>
</VirtualHost>

這裏的“/www/myApp”是存放項目的根目錄路徑。

可能前端的同學使用集成環境的比較多,如果不能完全理解的話,我拿uwamp環境做例子解析一下。
index.html文件:

<base href="/dist">

項目打包到dist文件中,然後把dist文件內容放到www下面,也就是www/dist裏面就是打包後的內容index.html以及各種js包,然後打開配置文件httpd.conf:

技術分享圖片

引入重寫rewrite模塊,找到#LoadModule rewrite_module modules/mod_rewrite.so,去掉前面的”#”:

技術分享圖片

添加規則:

<VirtualHost *:80>
    DocumentRoot "{DOCUMENTPATH}/"
    <Directory "{DOCUMENTPATH}/dist">
        Options FollowSymLinks
        AllowOverride All
        RewriteEngine On
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
        RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
        RewriteRule ^ - [L]
        RewriteRule ^ index.html
    </Directory>
</VirtualHost>

(3)重啟Apache
Apache1重啟

# service httpd restart

Apache2的重啟:

# /etc/init.d/apache2 restart

或者

# service apache2 restart 

uwamp環境的重啟,打開uwamp界面,先點擊關閉,然後再開啟即可:

技術分享圖片

(4)刷新頁面,會發現不再是404報錯了,設置成功。設置過程中需要留意的幾個坑是:

  • 沒有設置base-href,或者設置錯誤
  • Rewrite模塊沒有引入
  • 忘記重啟Apache

Angular2+如何去除url中的#