移除AngularJS+CodeIgniter网站URL的#后页面异常如何解决
我来帮你搞定这两个问题!当你去掉URL里的#开启AngularJS的HTML5模式后,出现刷新404和ng-view加载异常,本质是前后端路由的衔接没处理好,咱们一步步来解决:
先搞懂为啥会出问题
平时带#的路由是Angular在浏览器端自己处理的,不会真的请求服务器;但去掉#后,浏览器会直接把/items这类路径发给服务器,而CodeIgniter默认没有对应这些路径的路由,自然就返回404了。另外如果base href没设置对,Angular找不到正确的模板路径,ng-view就加载不出来。
第一步:把AngularJS的配置调对
首先得确保Angular的HTML5模式配置正确,还要设置好base href:
- 在你的主页面(比如CodeIgniter加载的
index视图)的<head>里加个base标签:
<base href="/">
要是你的网站部署在子目录(比如
http://xxx.com/myapp/),记得把href改成"/myapp/",不然路由会跑偏。
- 完善Angular的config代码,正式开启HTML5模式:
var app = angular.module('main-App', ['ngRoute','angularUtils.directives.dirPagination']); app.config(['$routeProvider','$locationProvider', function ($routeProvider,$locationProvider) { // 开启HTML5模式,去掉URL里的# $locationProvider.html5Mode(true).hashPrefix(''); $routeProvider .when('/', { templateUrl: 'templates/home.html', controller: 'AdminController' }) .when('/items', { templateUrl: 'templates/items.html', // 这里路径要确保能访问到 controller: 'ItemsController' }) // 加个默认路由,处理没匹配到的路径 .otherwise({ redirectTo: '/' }); }]);
第二步:让CodeIgniter把路由交给Angular处理
这是解决刷新404的关键,得让服务器把所有非静态资源的请求都转发到Angular的入口文件(也就是CodeIgniter的index.php):
如果你用的是Apache服务器
在项目根目录下新建或修改.htaccess文件,加这些规则:
RewriteEngine On # 允许访问真实存在的文件/文件夹(比如css、js、图片这些静态资源) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 其他所有请求都转发到index.php RewriteRule ^(.*)$ index.php/$1 [L]
要是用的是Nginx服务器
修改你的Nginx站点配置,在location /里加这段:
location / { try_files $uri $uri/ /index.php?$query_string; }
第三步:调整CodeIgniter的路由配置
打开application/config/routes.php,加个通配路由,让所有Angular的路由请求都指向你的主控制器(比如Welcome控制器的index方法,这个方法负责加载包含Angular的主页面):
// 保留原来的默认路由(可选) $route['default_controller'] = 'Welcome'; // 通配路由,把所有未匹配的请求都转给主视图 $route['(:any)'] = 'Welcome/index';
别忘了确认你的
Welcome控制器的index方法是对的,比如:public function index() { $this->load->view('index'); // 这个index视图就是包含Angular的主页面 }
第四步:检查模板路径是否正确
如果ng-view还是加载不出来,大概率是templateUrl的路径有问题。比如你把模板放在application/views/templates/下,直接写'templates/home.html'可能访问不到,这时候可以做个小调整:
新建一个Template控制器来返回模板内容:
class Template extends CI_Controller { public function get($templateName) { $this->load->view('templates/' . $templateName); } }
然后把Angular的路由改成:
.when('/', { templateUrl: 'template/get/home', controller: 'AdminController' })
最后验证一下
配置完重启服务器(如果需要),然后:
- 打开首页,看看URL里有没有#,
ng-view能不能正常加载内容; - 刷新页面或者直接输入
/items,确认不会跳404,对应的模板也能正常显示。
内容的提问来源于stack exchange,提问作者Tanwir Alam

