我想使用Angularjs'$locationProvider.html5Mode(true)
从网址中删除#hash。
示例:地址栏显示http://localhost/shop
而不是http://localhost/#/shop
。
一切正常,直到刷新页面。如果我刷新,则接受以下Laravel路由(在routes.php中定义)
Route::resource('shop', 'ShoppingController')
不是AngularJS路线(在app.js中定义)
$routeProvider.when('/shop', {
templateUrl: 'templates/shop.html',
controller: 'ShoppingController'
});
我的代码:
routes.php(Laravel Routes)
Route::get('/', function() {
return View::make('index');
});
Route::resource('shop', 'ShoppingController');
app.js(AngularJS Routes)
var app = angular.module('shoppingApp',['ngRoute','SharedServices']);
app.config(function($routeProvider, $locationProvider) {
$routeProvider.when('/shop', {
templateUrl: 'templates/shop.html',
controller: 'ShoppingController'
});
$routeProvider.otherwise({ redirectTo: '/' });
$locationProvider.html5Mode(true);
});
我的目录结构:
Project
/app
/...
/views
-index.php (single page application file)
-routes.php (Laravel routes)
/public
/...
/js
-angular.js
-app.js
-index.php (Laravel index file)
尝试过的解决方案:
重写htaccess文件,以便将所有请求重定向到index.php(单页应用程序文件,AngularJS将从该文件中接管路由)。问题:通过这种方式,Laravel路线(Route :: resource('shop','ShoppingController'); - 与数据库交互所必需的)变得无法访问AngularJS $ http服务:
app.js
app.controller("ShoppingController", function($scope, $http) {
$http.get('/shop', { cache: true}).
success(function(data, status) {
$scope.items = data
}).
error(function(data, status) {
console.log('Status: ' + status);
});
});
问题: 如何解决路由问题,以便在刷新localhost / shop时访问AngularJS路由,而不是Laravel路由?
答案 0 :(得分:7)
从我读到的内容来看,当您刷新页面时,Laravel似乎正在读取修改后的路线。在这种情况下,你应该让Laravel继续制作原始视图,即使它是404重定向。
尝试在Laravel端添加以下内容(例如routes.php)
App::missing(function($exception)
{
return View::make('index');
});
注意:您可能希望使用AngularJS的路由来处理未找到的网页。
答案 1 :(得分:5)
更好的解决方案是以这种方式重定向:
'重定向::到('/#/'。Request :: path())'
直接刷新或转到URI时:
最终解决方案:
App::missing(function($exception) {
return Redirect::to('/#/' . Request::path());
});
答案 2 :(得分:3)
如果您使用的是Laravel 5,请转到app/Exception/Handler.php
并输入以下代码:
public function render($request, Exception $e)
{
if($e instanceof NotFoundHttpException)
{
return Redirect::to('/#/' . Request::path());
}
return parent::render($request, $e);
}
答案 3 :(得分:0)
如果你有一个以上的单页应用程序在html5mode中运行,或者只是在Laravel应用程序中有另一个用于App :: missing的用法,你就会使用这样的重写规则:
#Redirect base url of AngularJS app in html5mode
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} ^/path/.+$
RewriteRule ^(path)/(.*) /path/#/$2 [R=301,L,NE]
答案 4 :(得分:0)
我有另一种解决方案,我发现它非常有用。我将URI传递给主页,而不是仅仅进行主页查看,主页将由控制器检查并相应地重定向(Angular方式)。这意味着,如果您在myapp.com/about上并刷新,而不是带您回家,则会将您带回到您当前所在的页面。
routes.php:请注意,我有一个URI通配符,我将其作为参数传递给回调函数,然后作为视图的变量传递。
// Note that this must be on the bottom of your routes file because
// if you have any registered route with a similar pattern
// it will get caught by this route and never reach any registered routes you might have
Route::get('{slug}', function($slug){
return View::make('index', compact('slug'));
});
// These routes will never get hit, so move them above Route::get('{slug}')
Route::get('about', function(){...});
Route::get('contact', function(){...});
index.blade.php:
<html ng-app"myApp">
<head>
...
</head>
<body>
<!--Check if there is a variable named $slug that is set-->
<!--If it is, set hidden input with ng-model-->
@if(isset($slug))
<input type="hidden" value="{{slug}}" ng-model="slug" ng-controller="RedirectController">
@endif
<div ng-view></div>
</body>
</html>
app.js
angular.module('myApp', [])
.controller('RedirectController', ['$location', '$scope', function ($location, $scope) {
// If slug is set, redirect to that slug
if ($scope.slug) {
$location.path('/' + $scope.slug);
}
}]);
答案 5 :(得分:0)
对于Laravel 4.x或5.x,我使用这个简单而好的技巧,无需更改.htaccess
文件。这个技巧很简单,适合我。它不会重定向URL,当刷新页面和页面刷新时,用户将保持相同的URL:
Route::get('dashboard/{all?}', function(){
return view('main.index');
});
这里我的仪表板应用程序是我的SPA。这样我们也可以解决404错误页面。