网站首页 > 基础教程 正文
最近,接到反馈说百度统计无法对 #号后的 URL 进行分析,需要前端去掉 URL 中的 #,下面分享一下关于这个问题的处理过程。
1、Angular2+ 路由策略
1.1 HashLocationStragegy
通过 hash 实现,当 URL 的 hash 发生改变时,触发 hashchange 注册的回调(低版本的浏览器没有 hashchange 事件,通过轮回检测 URL 实现),回调中去进行不同的操作,进行不同的内容展示。
使用 hash 来实现的话,URL 规则中要带上 #,路由中 # 后边的内容就是 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,实现重定向。
想对规则进行更多了解,请查看.htaccess rewrite 规则详细说明_Linux_脚本之家 ,下面说一下 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
3、小结
对于我们现在的 SPA 单页面应用(angular、vue、react) ,想去掉URL上的 “#” ,都可以用这样的配置思路:将路由 hash 模式改为 history 模式。
由于 history 模式下,改变 URL 路径后会重新请求资源,从而导致了404的情况,因此我们需要在服务器上做重定向配置回到我们 index 页面,重新匹配路由进行页面展示。
下期给大家分享更多实战中的点滴,如果大家喜欢 Angular 或对此感兴趣,欢迎各位关注、留言,大家的支持就是我的动力!
猜你喜欢
- 2024-11-14 angular8 ui-grid升级方案 angular8升级angular10
- 2024-11-14 angular8 日常开发避坑指南(30个)
- 2024-11-14 Angular 11.1.0-next.2 发布 angular 11发布的影响
- 2024-11-14 最近写Vue,真是累死人了!没有Angular爽,谁能帮帮我?[吐槽]
- 2024-11-14 Angular9构建一个后台管理系统(二)
- 2024-11-14 AngularJs入门,一个简单的demo angular实战
- 2024-11-14 Angular1升级到Angular2之组件样式封装
- 2024-11-14 逆袭之路系列-AngularJS 1.2版本编程入门-01
- 2024-11-14 Angular9构建一个后台管理系统(一)
- 2024-11-14 聊一聊新发布的Deno 2 deno怎么样了
- 06-18单例模式谁都会,破坏单例模式听说过吗?
- 06-18Objective-c单例模式的正确写法「藏」
- 06-18单例模式介绍(单例模式都有哪些)
- 06-18前端设计-单例模式在实战中的应用技巧
- 06-18PHP之单例模式(php单例模式连接数据库)
- 06-18设计模式:单例模式及C及C++实现示例
- 06-18python的单例模式(单例 python)
- 06-18你认为最简单的单例模式,东西还挺多
- 最近发表
- 标签列表
-
- jsp (69)
- gitpush (78)
- gitreset (66)
- python字典 (67)
- dockercp (63)
- gitclone命令 (63)
- dockersave (62)
- linux命令大全 (65)
- pythonif (86)
- location.href (69)
- dockerexec (65)
- tail-f (79)
- queryselectorall (63)
- location.search (79)
- bootstrap教程 (74)
- 单例 (62)
- linuxgzip (68)
- 字符串连接 (73)
- html标签 (69)
- c++初始化列表 (64)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)