我想为我的应用启用HTML5模式。我已为配置添加了以下代码,如here所示:
return app.config(['$routeProvider','$locationProvider', function($routeProvider,$locationProvider) {
$locationProvider.html5Mode(true);
$locationProvider.hashPrefix = '!';
$routeProvider.when('/', {
templateUrl: '/views/index.html',
controller: 'indexCtrl'
});
$routeProvider.when('/about',{
templateUrl: '/views/about.html',
controller: 'AboutCtrl'
});
正如您所看到的,我使用了$locationProvider.html5mode
并更改了ng-href
处的所有链接,以排除/#/
。
目前,我可以转到localhost:9000/
并查看索引页面并导航到localhost:9000/about
等其他页面。
但是,刷新localhost:9000/about
页面时会出现问题。我得到以下输出:Cannot GET /about
如果我查看网络电话:
Request URL:localhost:9000/about
Request Method:GET
如果我先转到localhost:9000/
,然后点击导航到/about
的按钮,我会得到:
Request URL:http://localhost:9000/views/about.html
这使页面完美呈现。
如何在刷新时启用角度来获取正确的页面?
答案 0 :(得分:99)
服务器端
使用此模式需要在服务器端重写URL,基本上您必须重写所有链接到应用程序的入口点(例如index.html)
原因是当您第一次访问该页面时/about
),例如刷新后,浏览器无法知道这不是真正的URL,因此它继续并加载它。但是,如果您首先加载了根页面以及所有javascript代码,那么当您导航到/about
时,Angular可以在浏览器尝试访问服务器并相应处理之前进入其中
答案 1 :(得分:62)
设置的内容很少,因此您在浏览器中的链接看起来像http://yourdomain.com/path
,这些是您的角配置+服务器端
1)AngularJS
$routeProvider
.when('/path', {
templateUrl: 'path.html',
});
$locationProvider
.html5Mode(true);
2)服务器端,只需将.htaccess
放入根文件夹并粘贴
RewriteEngine On
Options FollowSymLinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /#/$1 [L]
有关angularjs中html5模式和每个不同环境所需配置的更多有趣内容https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode 此问题也可能对您有所帮助$location / switching between html5 and hashbang mode / link rewriting
答案 2 :(得分:34)
我有类似的问题,我解决了它:
在索引页面中使用<base href="/index.html">
在我的node / Express服务器中使用catch all all route middleware,如下所示(把它放在路由器之后):
app.use(function(req, res) {
res.sendfile(__dirname + '/Public/index.html');
});
我认为这应该让你起步并运行。
如果您使用的是apache服务器,则可能需要mod_rewrite您的链接。这并不难。只需对配置文件进行一些更改。
所有这一切都假设你在angularjs上启用了html5mode。 现在。请注意,在角度1.2中,实际上不再推荐声明基本URL。
答案 3 :(得分:26)
BrowserSync和Gulp的解决方案。
来自https://github.com/BrowserSync/browser-sync/issues/204#issuecomment-102623643
首先安装connect-history-api-fallback
:
npm --save-dev install connect-history-api-fallback
然后将其添加到您的gulpfile.js:
var historyApiFallback = require('connect-history-api-fallback');
gulp.task('serve', function() {
browserSync.init({
server: {
baseDir: "app",
middleware: [ historyApiFallback() ]
}
});
});
答案 4 :(得分:13)
您需要配置服务器以将所有内容重写为index.html以加载应用程序:
答案 5 :(得分:10)
我编写了一个简单的连接中间件,用于模拟grunt项目的url重写。 https://gist.github.com/muratcorlu/5803655
您可以这样使用:
module.exports = function(grunt) {
var urlRewrite = require('grunt-connect-rewrite');
// Project configuration.
grunt.initConfig({
connect: {
server: {
options: {
port: 9001,
base: 'build',
middleware: function(connect, options) {
// Return array of whatever middlewares you want
return [
// redirect all urls to index.html in build folder
urlRewrite('build', 'index.html'),
// Serve static files.
connect.static(options.base),
// Make empty directories browsable.
connect.directory(options.base)
];
}
}
}
}
})
};
答案 6 :(得分:8)
如果您使用AngularJS与MVC进行.NET堆栈,则必须执行此操作才能删除&#39;#&#39;来自网址:
在_Layout页面中设置基本href:<head> <base href="/"> </head>
然后,在角度应用配置中添加以下内容:$locationProvider.html5Mode(true)
上面会移除&#39;#&#39;来自网址,但页面刷新不会工作,例如如果你在&#34; yoursite.com/about"页面刷新将给你一个404.这是因为MVC不知道角度路由,并且通过MVC模式,它将寻找关于&#39;关于&#39;在MVC路由路径中不存在。解决方法是将所有MVC页面请求发送到单个MVC视图,您可以通过添加捕获所有URL的路径来执行此操作
routes.MapRoute(
name: "App",
url: "{*url}",
defaults: new { controller = "Home", action = "Index" }
);
答案 7 :(得分:8)
IIS网址重写规则以防止在html5mode中页面刷新后出现404错误
对于Windows上的IIS下的角度运行
<rewrite>
<rules>
<rule name="AngularJS" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
在html5mode中页面刷新后阻止404错误的NodeJS / ExpressJS路由
对于Node / Express下的角度运行
var express = require('express');
var path = require('path');
var router = express.Router();
// serve angular front end files from root path
router.use('/', express.static('app', { redirect: false }));
// rewrite virtual urls to angular app to enable refreshing of internal pages
router.get('*', function (req, res, next) {
res.sendFile(path.resolve('app/index.html'));
});
module.exports = router;
更多信息:AngularJS - Enable HTML5 Mode Page Refresh Without 404 Errors in NodeJS and IIS
答案 8 :(得分:5)
正如其他人所提到的,您需要在服务器上重写路由并设置<base href="/"/>
。
gulp-connect
:
npm install connect-pushstate
var gulp = require('gulp'),
connect = require('gulp-connect'),
pushState = require('connect-pushstate/lib/pushstate').pushState;
...
connect.server({
...
middleware: function (connect, options) {
return [
pushState()
];
}
...
})
....
答案 9 :(得分:4)
我在开发环境中使用apache(xampp),并在生产中使用apache, 添加:
errorDocument 404 /index.html
到.htaccess解决了这个问题。
答案 10 :(得分:3)
我解决了
test: {
options: {
port: 9000,
base: [
'.tmp',
'test',
'<%= yeoman.app %>'
],
middleware: function (connect) {
return [
modRewrite(['^[^\\.]*$ /index.html [L]']),
connect.static('.tmp'),
connect().use(
'/bower_components',
connect.static('./bower_components')
),
connect.static('app')
];
}
}
},
答案 11 :(得分:3)
我从更大的问题回答这个问题:
当我添加$ locationProvider.html5Mode(true)时,我的网站将不允许粘贴网址。当html5Mode为true时,如何配置我的服务器?
启用html5Mode后,您的网址中将不再使用#字符。 #符号很有用,因为它不需要服务器端配置。没有#,url看起来更好,但它也需要服务器端重写。以下是一些例子:
对于使用AngularJS的Express重写,您可以使用以下更新来解决此问题:
app.get('/*', function(req, res) {
res.sendFile(path.join(__dirname + '/public/app/views/index.html'));
});
和
<!-- FOR ANGULAR ROUTING -->
<base href="/">
和
app.use('/',express.static(__dirname + '/public'));
答案 12 :(得分:3)
对于Grunt和Browsersync,请使用connect-modrewrite here
var modRewrite = require('connect-modrewrite');
browserSync: {
dev: {
bsFiles: {
src: [
'app/assets/css/*.css',
'app/*.js',
'app/controllers/*.js',
'**/*.php',
'*.html',
'app/jade/includes/*.jade',
'app/views/*.html',
],
},
options: {
watchTask: true,
debugInfo: true,
logConnections: true,
server: {
baseDir :'./',
middleware: [
modRewrite(['!\.html|\.js|\.jpg|\.mp4|\.mp3|\.gif|\.svg\|.css|\.png$ /index.html [L]'])
]
},
ghostMode: {
scroll: true,
links: true,
forms: true
}
}
}
},
答案 13 :(得分:2)
我们在Express中有一个服务器重定向:
app.get('*', function(req, res){
res.render('index');
});
即使我们添加了<base href="/" />
。
解决方案:确保您使用页面中的真实链接进行导航;不要在URL中输入路线,否则您将获得页面刷新。 (愚蠢的错误,我知道)
: - P
答案 14 :(得分:2)
我相信您的问题与服务器有关。有关HTML5模式的角度文档(在您的问题中的链接)指出:
服务器端 使用此模式需要在服务器端重写URL,基本上您必须重写所有链接到应用程序的入口点(例如index.html)
我相信你需要设置一个url重写/关于/.
答案 15 :(得分:1)
最后我找到了一种方法来解决服务器端的问题,因为它更像是AngularJs本身的问题我使用的是1.5 Angularjs,我在重新加载页面时遇到了同样的问题。
但是在我的server.js
文件中添加以下代码后,我将保存 ,但这不是一个正确的解决方案,也不是一个好方法。
app.use(function(req, res, next){
var d = res.status(404);
if(d){
res.sendfile('index.html');
}
});
答案 16 :(得分:0)
我已通过在node.js文件中添加以下代码段来解决此问题。
app.get("/*", function (request, response) {
console.log('Unknown API called');
response.redirect('/#' + request.url);
});
注意:当我们刷新页面时,它会查找API而不是Angular页面(因为URL中没有#tag)。使用上面的代码,我用#
重定向到url答案 17 :(得分:0)
我找到了更好的Grunt插件,如果你将index.html和Gruntfile.js放在同一个目录中,那就有用了;
https://npmjs.org/package/grunt-connect-pushstate
之后在你的Gruntfile中:
var pushState = require('grunt-connect-pushstate/lib/utils').pushState;
connect: {
server: {
options: {
port: 1337,
base: '',
logger: 'dev',
hostname: '*',
open: true,
middleware: function (connect, options) {
return [
// Rewrite requests to root so they may be handled by router
pushState(),
// Serve static files
connect.static(options.base)
];
}
},
}
},
答案 18 :(得分:0)
我有这个我一直在使用的简单解决方案及其作品。
在App / Exceptions / Handler.php
中在顶部添加:
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
然后在渲染方法
中public function render($request, Exception $exception)
{
.......
if ($exception instanceof NotFoundHttpException){
$segment = $request->segments();
//eg. http://site.dev/member/profile
//module => member
// view => member.index
//where member.index is the root of your angular app could be anything :)
if(head($segment) != 'api' && $module = $segment[0]){
return response(view("$module.index"), 404);
}
return response()->fail('not_found', $exception->getCode());
}
.......
return parent::render($request, $exception);
}
答案 19 :(得分:0)
您的服务器端代码是JAVA,然后按照以下步骤
执行第1步:下载urlrewritefilter JAR Click Here 并保存到构建路径WEB-INF / lib
第2步:启用HTML5模式$ locationProvider.html5Mode(true);
第3步:设置基本网址<base href="/example.com/"/>
第4步:复制并粘贴到WEB.XML
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
步骤5:在WEN-INF / urlrewrite.xml中创建文件
<urlrewrite default-match-type="wildcard">
<rule>
<from>/</from>
<to>/index.html</to>
</rule>
<!--Write every state dependent on your project url-->
<rule>
<from>/example</from>
<to>/index.html</to>
</rule>
</urlrewrite>
答案 20 :(得分:0)
Gulp + browserSync:
通过npm安装connect-history-api-fallback,稍后配置你的服务gulp任务
var historyApiFallback = require('connect-history-api-fallback');
gulp.task('serve', function() {
browserSync.init({
proxy: {
target: 'localhost:' + port,
middleware: [ historyApiFallback() ]
}
});
});
答案 21 :(得分:0)
使用 JHipster 生成的 java + angular app遇到了同样的问题。 我用过滤器和属性中所有角度页面的列表解决了它:
<强> application.yml:强>
angular-pages:
- login
- settings
...
<强> AngularPageReloadFilter.java 强>
public class AngularPageReloadFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.getRequestDispatcher("index.html").forward(request, response);
}
}
<强> WebConfigurer.java 强>
private void initAngularNonRootRedirectFilter(ServletContext servletContext,
EnumSet<DispatcherType> disps) {
log.debug("Registering angular page reload Filter");
FilterRegistration.Dynamic angularRedirectFilter =
servletContext.addFilter("angularPageReloadFilter",
new AngularPageReloadFilter());
int index = 0;
while (env.getProperty("angular-pages[" + index + "]") != null) {
angularRedirectFilter.addMappingForUrlPatterns(disps, true, "/" + env.getProperty("angular-pages[" + index + "]"));
index++;
}
angularRedirectFilter.setAsyncSupported(true);
}
希望,这会对某人有所帮助。
答案 22 :(得分:0)
I solved same problem using modRewrite.
AngularJS is reload page when after # changes.
But HTML5 mode remove # and invalid the reload.
So we should reload manually.
# install connect-modrewrite
$ sudo npm install connect-modrewrite --save
# gulp/build.js
'use strict';
var gulp = require('gulp');
var paths = gulp.paths;
var util = require('util');
var browserSync = require('browser-sync');
var modRewrite = require('connect-modrewrite');
function browserSyncInit(baseDir, files, browser) {
browser = browser === undefined ? 'default' : browser;
var routes = null;
if(baseDir === paths.src || (util.isArray(baseDir) && baseDir.indexOf(paths.src) !== -1)) {
routes = {
'/bower_components': 'bower_components'
};
}
browserSync.instance = browserSync.init(files, {
startPath: '/',
server: {
baseDir: baseDir,
middleware: [
modRewrite([
'!\\.\\w+$ /index.html [L]'
])
],
routes: routes
},
browser: browser
});
}
答案 23 :(得分:-2)
只需在web.config中写出规则
<system.webServer>
<rewrite>
<rules>
<rule name="AngularJS Routes" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
<add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
</conditions>
<action type="Rewrite" url="/" />
</rule>
</rules>
</rewrite>
</system.webServer>
在索引中添加此
<base href="/">
它对我有用,也许你已经忘记设置Html5Mode app.config
app.config(function ($stateProvider, $urlRouterProvider, $locationProvider){
$locationProvider.html5Mode({ enabled: true, requireBase: true });
$locationProvider.hashPrefix('!');
}