property - Recargar la página da una solicitud GET incorrecta con el modo AngularJS HTML5
ng src angular 6 (24)
Como han mencionado otros, debe volver a escribir las rutas en el servidor y establecer <base href="/"/>
.
Para 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()
];
}
...
})
....
Quiero habilitar el modo HTML5 para mi aplicación. He puesto el siguiente código para la configuración, como se muestra 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''
});
Como puede ver, utilicé $locationProvider.html5mode
y cambié todos mis enlaces en ng-href
para excluir el /#/
.
El problema
En este momento, puedo ir a localhost:9000/
y ver la página de índice y navegar a las otras páginas como localhost:9000/about
.
Sin embargo, el problema ocurre cuando actualizo el localhost:9000/about
page. Me sale el siguiente resultado: Cannot GET /about
Si miro las llamadas de la red:
Request URL:localhost:9000/about
Request Method:GET
Mientras que si primero voy a localhost:9000/
y luego hago clic en un botón que navega a /about
, obtengo:
Request URL:http://localhost:9000/views/about.html
Lo que hace que la página se vea perfectamente.
¿Cómo puedo habilitar angular para obtener la página correcta cuando actualizo?
Creo que su problema es con respecto al servidor. La documentación angular con respecto al modo HTML5 (en el enlace de su pregunta) establece:
Lado del servidor El uso de este modo requiere la reescritura de URL en el servidor, básicamente, debe volver a escribir todos sus enlaces al punto de entrada de su aplicación (por ejemplo, index.html)
Creo que necesitarás configurar una reescritura de URL desde / hasta a /.
De los documentos angulares.
Lado del servidor
El uso de este modo requiere la reescritura de URL en el servidor, básicamente, debe volver a escribir todos sus enlaces al punto de entrada de su aplicación (por ejemplo, index.html)
La razón de esto es que cuando visita la página por primera vez ( /about
), por ejemplo, después de una actualización, el navegador no tiene forma de saber que esta no es una URL real, por lo que sigue adelante y la carga. Sin embargo, si primero ha cargado la página raíz y todo el código javascript, cuando navega a /about
Angular puede ingresar antes de que el navegador intente acceder al servidor y manejarlo en consecuencia.
Debe configurar su servidor para volver a escribir todo en index.html para cargar la aplicación:
El código del lado del servidor es JAVA, luego siga los pasos a continuación
paso 1: descargue el JAR de urlrewritefilter Haga clic aquí y guárdelo para crear la ruta WEB-INF / lib
paso 2: habilitar el modo HTML5 $ locationProvider.html5Mode (true);
paso 3: establecer la URL base <base href="/example.com/"/>
paso 4: copiar y pegar en tu 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>
paso 5: crea un archivo en 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>
Escribí un middleware de conexión simple para simular la reescritura de url en proyectos grunt. https://gist.github.com/muratcorlu/5803655
Se puede usar así:
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)
];
}
}
}
}
})
};
Estoy respondiendo esta pregunta de la pregunta más grande:
Cuando agrego $ locationProvider.html5Mode (verdadero), mi sitio no permitirá pegar URL. ¿Cómo configuro mi servidor para que funcione cuando html5Mode es verdadero?
Cuando tiene habilitado el modo html5, el carácter # ya no se utilizará en sus direcciones URL. El símbolo # es útil porque no requiere configuración del lado del servidor. Sin #, la url se ve mucho mejor, pero también requiere la reescritura del lado del servidor. Aquí hay unos ejemplos:
Para Express Rewrites con AngularJS, puede resolver esto con las siguientes actualizaciones:
app.get(''/*'', function(req, res) {
res.sendFile(path.join(__dirname + ''/public/app/views/index.html''));
});
y
<!-- FOR ANGULAR ROUTING -->
<base href="/">
y
app.use(''/'',express.static(__dirname + ''/public''));
Estoy usando apache (xampp) en mi entorno dev y apache en la producción, agregue:
errorDocument 404 /index.html
Para el .htaccess resuélveme este problema.
Finalmente, conseguí una forma de resolver este problema por parte del servidor, ya que es más bien un problema con AngularJs. Estoy usando 1.5 Angularjs y obtuve el mismo problema al volver a cargar la página. Pero después de agregar el código a continuación en mi archivo server.js
, es guardar mi día, pero no es una solución adecuada o no es una buena manera.
app.use(function(req, res, next){
var d = res.status(404);
if(d){
res.sendfile(''index.html'');
}
});
Hay algunas cosas que configurar para que su enlace en el navegador se vea como http://yourdomain.com/path
y estos sean su lado de configuración angular + servidor
1) AngularJS
$routeProvider
.when(''/path'', {
templateUrl: ''path.html'',
});
$locationProvider
.html5Mode(true);
2) del lado del servidor, simplemente coloque .htaccess
dentro de su carpeta raíz y pegue esto
RewriteEngine On
Options FollowSymLinks
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /#/$1 [L]
Más cosas interesantes para leer sobre el modo html5 en angularjs y la configuración requerida para cada entorno diferente https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode También esta pregunta puede ayudarlo a $ ubicación / cambio entre modo html5 y hashbang / reescritura de enlaces
He encontrado un complemento Grunt aún mejor, que funciona si tiene su index.html y Gruntfile.js en el mismo directorio;
https://npmjs.org/package/grunt-connect-pushstate
Después de eso en tu 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)
];
}
},
}
},
He resuelto el problema agregando el siguiente fragmento de código en el archivo node.js.
app.get("/*", function (request, response) {
console.log(''Unknown API called'');
response.redirect(''/#'' + request.url);
});
Nota: cuando actualizamos la página, buscará la API en lugar de la página Angular (debido a que no hay etiqueta # en la URL). Usando el código anterior, estoy redirigiendo a la url con #
Para Grunt y Browsersync use 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
}
}
}
},
Resolví a
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'')
];
}
}
},
Si está en la pila .NET con MVC con AngularJS, esto es lo que debe hacer para eliminar el ''#'' de la url:
Configure su base href en su página _Disposición:
<head> <base href="/"> </head>
Luego, agregue lo siguiente en la configuración de la aplicación angular:
$locationProvider.html5Mode(true)
Anteriormente eliminará ''#'' de la URL, pero la actualización de la página no funcionará, por ejemplo, si está en la actualización de la página "yoursite.com/about" le dará un 404. Esto se debe a que MVC no conoce el enrutamiento angular y, según el patrón de MVC buscará una página de MVC para ''about'' que no existe en la ruta de enrutamiento de MVC. La solución para esto es enviar todas las solicitudes de página de MVC a una sola vista de MVC y puede hacerlo agregando una ruta que atrape toda la url
routes.MapRoute(
name: "App",
url: "{*url}",
defaults: new { controller = "Home", action = "Index" }
);
Solo escribe una regla en 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>
En el índice agregue esto.
<base href="/">
funciona para mí, quizás haya olvidado configurar Html5Mode app.config
app.config(function ($stateProvider, $urlRouterProvider, $locationProvider){
$locationProvider.html5Mode({ enabled: true, requireBase: true });
$locationProvider.hashPrefix(''!'');
}
Solución para BrowserSync y Gulp.
Desde https://github.com/BrowserSync/browser-sync/issues/204#issuecomment-102623643
Primero instale connect-history-api-fallback
:
npm --save-dev install connect-history-api-fallback
Luego agrégalo a tu gulpfile.js:
var historyApiFallback = require(''connect-history-api-fallback'');
gulp.task(''serve'', function() {
browserSync.init({
server: {
baseDir: "app",
middleware: [ historyApiFallback() ]
}
});
});
Tengo esta solución simple que he estado usando y su trabajo.
En la aplicación / Excepciones / Handler.php
Agregue esto en la parte superior:
use Symfony/Component/HttpKernel/Exception/NotFoundHttpException;
Luego dentro del método de render
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);
}
Tuve el mismo problema con la aplicación java + angular generada con JHipster . Lo resolví con Filtro y lista de todas las páginas angulares en propiedades:
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);
}
Esperanza, será de ayuda para alguien.
Tuve un problema similar y lo resolví por:
Usando
<base href="/index.html">
en la página de índiceUsando un middleware catch all route en mi nodo / servidor Express de la siguiente manera (póngalo después del enrutador):
app.use(function(req, res) {
res.sendfile(__dirname + ''/Public/index.html'');
});
Creo que eso debería ponerte en marcha.
Si usa un servidor apache, puede querer mod_rewrite sus enlaces. No es difícil de hacer. Sólo unos pocos cambios en los archivos de configuración.
Todo lo que se supone que tienes habilitado html5mode en angularjs. Ahora. tenga en cuenta que en angular 1.2, declarar una base url ya no se recomienda en realidad.
Tuvimos una redirección de servidor en Express:
app.get(''*'', function(req, res){
res.render(''index'');
});
y seguíamos teniendo problemas de actualización de página, incluso después de que agregáramos <base href="/" />
.
Solución: asegúrese de que está usando enlaces reales en su página para navegar; no escriba la ruta en la URL o obtendrá una actualización de la página. (error tonto, lo sé)
:-PAG
Gulp + browserSync:
Instale connect-history-api-fallback a través de npm, más tarde configure su tarea de servicio.
var historyApiFallback = require(''connect-history-api-fallback'');
gulp.task(''serve'', function() {
browserSync.init({
proxy: {
target: ''localhost:'' + port,
middleware: [ historyApiFallback() ]
}
});
});
La regla de reescritura de URL de IIS para evitar el error 404 después de la actualización de la página en html5mode
Para ejecución angular bajo IIS en Windows
<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>
Rutas de NodeJS / ExpressJS para evitar el error 404 después de la actualización de la página en html5mode
Para funcionamiento angular bajo Nodo / Expreso
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;
Más información en: AngularJS - Habilitar la actualización de la página del modo HTML5 sin errores 404 en NodeJS e IIS
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
});
}