为什么要去除?

  1. Angular官方指出:如果没有足够使用hash风格(#)的理由,还是尽量使用HTML5模式的路由风格;
  2. 如果配置了hash风格,在微信支付或是Angular的深路径依然会出404的问题;
  3. 当你需要使用GA等工具时,由于无法获取#号后的URL,导致每次路由切换都给其发送一个路径;
  4. '#'有点丑。

怎样才能去除?

有四个方法:

  1. 前端 + ngx
  2. 前端 + Apache
  3. 前端 + Tomcat
  4. GithubPages / 码云 Pages + 404 页面

前端

index.html的head里加

<base href="/">

app.module.ts

import { ROUTER_CONFIG } from './app.routes.ts';
@NgModule({imports: [...RouterModule.forRoot(ROUTER_CONFIG) //  RouterModule.forRoot(ROUTER_CONFIG, { useHash: true } )   这样写是带#的],
})

app.routes.ts:

import { NgModule } from '@angular/core';
import { Routes } from '@angular/router';export const ROUTER_CONFIG: Routes = [{...}
];

如果只配置前端会怎么样?

如果只配置前端虽然会去掉’#'但是一刷新页面就404,路径解析上出错了。
Angular是单页应用,它实现了前端路由功能,后台可以不再控制路由的跳转,将原本属于后端的业务逻辑全部丢给前端。

用户刷新页面时(http://gitee.poetry/life),请求是先被提交到了WebServer后台,后台路由没有对应页面的路由管理,就会出现404的错误。

用户如果是先访问首页(http://gitee.poetry),然后再跳转到 页面(http://gitee.poetry/life),则这个跳转是由Angular前台管理的URL,访问是正常的。

那么我们让WebServer把属于Angular管理的路由URL,都转发到index.html就可以解决404的问题了,也就是后面介绍的配置信息。

思考:hash模式为什么不会404?

Nginx配置

带***的是需要自己配置 nginx.conf 文件内容

server {listen 80;  #监听的端口号 server_name  my_server_name; # 服务器名称  ***root   /projects/angular/myproject/dist;  #相对于nginx的位置 ***index index.html; #如果index.html存在,就结束查找过程,把这个文件附加到请求的request_uri后面,并且发起一个内部的redirect。location / {  # / 是匹配所有的uri后执行下面操作try_files $uri $uri/ /index.html; #try_files先寻找名为 $uri 文件,没有则寻找 $uri/ 文件,再没有就寻找/index.html}
}
try_files 详细解释:

如请求的是https://deepthan.gitee.io/poetry/life, $uri则是‘/life’,如果‘$uri’‘$uri/’都找不到,就会 fall back 到 try_files 的最后一个选项 /index.html发起一个内部 “子请求”,也就是相当于 nginx 发起一个 HTTP 请求到https://deepthan.gitee.io/poetry/index.html。这个请求会被 location ~ .php$ { … } catch 住,也就是进入 FastCGI 的处理程序。而具体的 URI 及参数是在 REQUEST_URI 中传递给 FastCGI 和 WordPress 程序的,因此不受 URI 变化的影响。

Apache

Apache的根目录新建一个.htaccess文件

RewriteEngine On
# 如果请求的是现有资源,则按原样执行
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]# 如果请求的资源不存在,则使用index.html
RewriteRule ^ /index.html

Tomcat配置

Tomcat/conf/web.xml文件上添加

<error-page><error-code>404</error-code><location>/</location>
</error-page>

GithubPages / 码云 Pages + 404 页面

对于github pages或码云 Pages来说,我们没办法直接配置Github pages,但可以在commit时添加一个404页。简单的解决方案如下:
我们在项目的根目录新建404.html,把index.html中的内容完全复制到404.html中就可以了。这样做github pages仍然会在恰当的时候给出一个404响应,浏览器将会正确处理该页,并正常加载我们的应用。

关于这方面的hack: S(GH)PA: The Single-Page App Hack for GitHub Pages

带‘#’和不带‘#’原理上有什么区别呢?

这个得先说下什么是前端路由:

以前路由都是后台做的,通过用户请求的url导航到具体的html页面,现在我们在前端可以利用 Angular、vue、react等通过配置文件,达到前端控制路由跳转的功能。
前端路由的实现方法:

  1. 通过hash实现
    当url的hash发生改变时,触发hashchange注册的回调(低版本没有hashchange事件,通过轮回检测url实现),回调中去进行不同的操作,进行不同的内容展示。
    使用hash来实现的话,URI规则中要带上#,路由中#后边的内容就是hash,我们常说的锚点严格来说应该是页面中的a[name]等元素。

  2. HTML5的history api操作浏览器的session history实现
    基于history实现的路由中不带#,就是原始的路由

Angular中的路由策略

angular2提供的路由策略也是基于上面两个原理实现的,可以在@NgModule中通过providers配置或RouterModule.forRoot()配置:
1) 路由中有#

@NgModule({imports:[RouterModule.forRoot(routes,{useHash:true})]
})

@NgModule({imports:[RouterModule.forRoot(routes)],providers:[{provide: LocationStrategy, useClass: HashLocationStrategy} ]
})

HashLocationStragegy
适用于基于锚点标记的路径,比如/#/**,后端只需要配置一个根路由即可。

2) html5路由(无#)
改用 PathLocationStrategy(angular2的默认策略,也就是HTML5路由),使用这个路由的常规路径不带#,这种策略需要后台配置支持,因为我们的应用是单页面应用,如果后台没有正确的配置,当用户在浏览器从一个路由跳往另外一个路由或者刷新时就会返回404,需要在服务端里面覆盖所有的路由情况(后端可以通过nginx或者apache等配置)。

@NgModule({imports:[RouterModule.forRoot(routes)],providers:[{provide: LocationStrategy, useClass: PathLocationStrategy} // 这一行是可选的,因为默认的LocationStrategy是PathLocationStrategy]
})

更改index.html中的base href属性,Angular将通过这个属性来处理路由跳转

<base href="/app/">

在后端的服务器上,用下面的正则去匹配所有的页面请求导向index.html页面。

we must render the index.html file for any request coming with below pattern

index.html

<!doctype html>
<html>
<head><meta charset="utf-8"><title>My App</title><base href="/app/"><body><app-root>Loading...</app-root><script type="text/javascript" src="vendor.bundle.js"></script><script type="text/javascript" src="main.bundle.js"></script></body>
</html>

前端路由优缺点

优点:
1.从性能和用户体验的层面来比较的话,后端路由每次访问一个新页面的时候都要向服务器发送请求,然后服务器再响应请求,这个过程肯定会有延迟。而前端路由在访问一个新页面的时候仅仅是变换了一下路径而已,没有了网络延迟,对于用户体验来说会有相当大的提升。
2.在某些场合中,用ajax请求,可以让页面无刷新,页面变了但Url没有变化,用户不能获取到想要的url地址,用前端路由做单页面网页就很好的解决了这个问题。

缺点:
使用浏览器的前进,后退键的时候会重新发送请求,没有合理地利用缓存。

文章来源

作者:莫莫莫
链接:https://juejin.im/post/5a39c10351882538d3101129
来源:掘金

Angular4 去掉url中的#,并解决刷新时的404问题相关推荐

  1. wordpress去掉index.php,wordpress去掉url中index.php 创建分类目录404如何解决

    wordpress主题是建设个人博客的首选,便利简洁.今天整理2个wp建站过程中常遇到的两个问题,整理了下来.相信很初用wp的伙伴都遇到这样的问题,url中包含index.php,这样的url很不美观 ...

  2. zencart分类页产品页去掉url中的id号

    最近公司新上的网站被seo指出要修改url,去掉url中产品id.由于我们用的是zencart框架,装了 Ultimate SEO URLs 插件,所以在网上应该有这方面的资料,本文主要参考资料: 原 ...

  3. php 去掉url中的index.php,php 去掉url中的index.php

    php去掉url中的index.php的方法:首先打开相应的代码文件:然后将if代码块嵌套在server代码块中:最后重启nginx服务器即可. 本文操作环境:nginx1.0.4系统.PHP7.1版 ...

  4. url去除掉一个参数php,php怎样去掉url中的参数_后端开发

    php去掉url中的参数的要领是:能够经由过程trim()函数来完成.该函数能够删除字符串中的指定字符,并返回已修正的字符串.细致使用要领如:[trim($url,"?");tri ...

  5. codeigniter:去掉 URL 中的 index.php

    去掉 URL 中的 index.php 首先,你要清楚自己的 Web 服务器是 Apache,支持 mod_rewrite,并且已经配置好 rewrite 相关的参数. 什么是 rewrtie 可以 ...

  6. servlet和action中获取URL中的汉字(解决URL中汉字为乱码的问题) .

    2019独角兽企业重金招聘Python工程师标准>>> 最近在项目中又遇到一个小问题,通过HttpURLConnection来传递汉字时,服务端获取汉字参数时都为乱码,以下分别为在s ...

  7. nginx反向代理和rewrite进行解决跨域问题、去掉url中的一部分字符串,通过nginx正则生成新的url...

    场景:表面上访问的是http://127.0.0.1:7777/test/xhtml//tpl/app-tpl-webapp/css/base.css, 实际上看的是http://127.0.0.1: ...

  8. nginx反向代理和rewrite进行解决跨域问题、去掉url中的一部分字符串,通过nginx正则生成新的url

    场景:表面上访问的是http://127.0.0.1:7777/test/xhtml//tpl/app-tpl-webapp/css/base.css, 实际上看的是http://127.0.0.1: ...

  9. Apache Shiro去掉URL中的JSESSIONID

    最近集成框架用到shiro碰到url有时候会带上jsessionid有时候又没有.以前也碰到但是没有深入研究. 网上查了半天各种方法用了都没用.比如web.xml里面加session-config,添 ...

最新文章

  1. Codeforces Round #308 (Div. 2) C. Vanya and Scales dfs
  2. linux 中 timeval结构体 - Neddy11 - 博客园
  3. RxAndroid之操作数据库SqlBrite(RXAndroid实现数据库的增、删、改、查)
  4. java代码连接数据库
  5. 前端学习(3267):js中this在类中的表现
  6. 含有js的英文单词_JavaScript 常用单词整理
  7. 图形学理论 光照模型
  8. Echarts常用配置参数
  9. php套壳_PHP-T
  10. C语言程序设计谭浩强第五版复习梳理3
  11. Android 杂七杂八记录
  12. 22.11.16 IO day 8
  13. 机器学习算法(一):基于逻辑回归的分类预测
  14. drupal7 php版本,为内置PHP 5.4服务器提供Drupal 7
  15. IOS:IOS集成开发和环境的介绍
  16. 转一个PS图像处理技巧大全,很实用!
  17. 开机、重启和用户登录注销
  18. 高考填志愿—利用大数据填报
  19. Dynamics AX2012 AOT同步到VS
  20. 电商宝SCRM/微信个人号管家v1.1.0成功发布,支持个人号红包收发/批量加好友!...

热门文章

  1. html如何使mp4成为背景,如何让MP4 video视频背景色变成透明?
  2. createjs图片不清晰的坑
  3. python 秘钥_python 生成ssh秘钥对
  4. 三星程序员晒源码泄露机密
  5. Java -- 如何解决某些情况下,前台向后台传参时,alert 等敏感字符被和谐
  6. 比赛的心得和感想--邱波
  7. 有向无环图——AOE网(关键路径)
  8. Mars 模拟器编写 mips32 汇编 的入门教程
  9. 差分数组分析详解+例题
  10. 厦门大学校园导游系统(图论)