如何捕获并重定向Angular框架外的非哈希格式URL?
解决Angular哈希模式下无哈希URL无法重定向的问题
咱们先把问题根源理清楚:当你访问http://localhost/random这类不带哈希的URL时,浏览器会直接向服务器发起真实的GET请求,但你的服务器上并没有/random这个实际存在的文件或路由,所以返回Cannot GET /random错误。而带#的URL(比如http://localhost/#/random),浏览器只会把#后面的内容当作页面内锚点,不会发送给服务器,所以Angular的路由系统能捕获到这个路径,触发$urlRouterProvider.otherwise('/login')的重定向逻辑。
要解决这个问题,核心是让服务器把所有非静态资源的请求都转发到Angular的入口文件index.html,这样Angular就能接管路由处理,进而执行你的重定向规则。下面分不同服务器环境给出具体配置:
1. Apache服务器配置
在你的Angular项目根目录创建.htaccess文件,写入以下规则:
RewriteEngine On RewriteBase / RewriteRule ^index\.html$ - [L] # 如果请求的不是文件或目录,转发到index.html RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule . /index.html [L]
2. Nginx服务器配置
在你的Nginx站点配置的server块中添加如下规则:
location / { # 先尝试访问文件、目录,找不到就返回index.html try_files $uri $uri/ /index.html; }
3. Node.js Express服务器配置
如果用Express托管静态资源,添加一个全局路由来兜底返回index.html:
const express = require('express'); const app = express(); const path = require('path'); // 托管Angular构建后的静态资源(假设产物在dist目录) app.use(express.static(path.join(__dirname, 'dist'))); // 所有非静态资源请求都返回index.html app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'dist/index.html')); }); app.listen(3000, () => console.log('Server running on port 3000'));
额外选项:切换到HTML5模式(去掉URL中的哈希)
如果你想彻底去掉URL里的#,可以开启Angular的HTML5模式:
angular.module('myApp').config(function($stateProvider, $urlRouterProvider, $locationProvider) { $urlRouterProvider.otherwise('/login'); // 开启HTML5模式 $locationProvider.html5Mode(true); $stateProvider .state('test',{ url:'/test', templateUrl: 'views/test.html' }) .state('login',{ url:'/login', templateUrl: 'views/login.html' }); })
同时需要在index.html的<head>标签里添加<base href="/">,指定应用的基础路径。注意:开启HTML5模式后,依然需要配置上面的服务器规则,否则刷新页面还是会出现404错误。
内容的提问来源于stack exchange,提问作者opticyclic
相关产品推荐
相关产品推荐

