Angular2 without hash in the url - html

Now, my website's url looks like this because I'm using the approach described here
http://localhost:4200/#/cadastro
Is it possible to remove the hash in the url and not get the 404 error?
EDIT: Router Module added
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'cadastro', component: CadastroNoivosComponent },
{ path: '**', component: HomeComponent }
];
export const routing = RouterModule.forRoot(appRoutes);

If you are using Angular final, the reasons to the hash could be:
RouterModule.forRoot(yourRoutesHere, { useHash: true })
So by removing that could help.
RouterModule.forRoot(yourRoutesHere)
Alternatively if you in your providers (in NgModule) have used:
{provide: LocationStrategy, useClass: HashLocationStrategy}
just remove that.
EDIT, if you need LocationStrategy, try changing HashLocationStrategy to PathLocationStrategy:
{provide: LocationStrategy, useClass: PathLocationStrategy}
More about LocationStrategy here
Now that I have seen your routes as well regarding your 404 issue, you could try changing the following
{ path: '**', component: HomeComponent }
to:
{ path: '**', redirectTo: '', pathMatch: 'full' }
More about routing here
Also check that in your index.html you have set the basehref like so:
<base href="/">

If you use PathLocationStrategy as describe here you can remove the hash in the URL.
But getting rid of 404 error needs some server side tweak. A quick and easy way is to configure your server to load the home page when any URL of the form http://yourhost/* is requested.

Create a .htaccess file Paste the following Code And Upload on your prod Server.
RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.html [L]

Related

refreshing the page results in 404 error- Angular 6

I am building an application with the help of Angular6 and facing problems in routing. All the routes are working when I click on a particular tab but whenever I refresh the current page, it is throwing 404 error. I have seen many posts regarding this issue on Stack overflow but failed to overcome from this problem.
Below is my app.module.ts
import {BrowserModule} from '#angular/platform-browser';
import {NgModule} from '#angular/core';
import {RouterModule, Routes} from '#angular/router';
import {AppComponent} from './app.component';
import {FetchApiComponent} from './fetch-api/fetch-api.component';
import {FormsModule} from '#angular/forms';
import {HttpClientModule} from '#angular/common/http';
import {UserServiceLatest} from './fetch-latest/app.service';
import {UserServiceTop} from './fetch-top/app.service';
import {YoutubePlayerModule} from 'ngx-youtube-player';
import {SidebarComponent} from './sidebar/sidebar.component';
import {FetchLatestComponent} from './fetch-latest/fetch-latest.component';
import { FetchTopComponent } from './fetch-top/fetch-top.component'
import {UserService} from './fetch-api/app.service';
import { ServiceWorkerModule } from '#angular/service-worker';
import { environment } from '../environments/environment';
import { AngularFireModule } from 'angularfire2';
import * as firebase from 'firebase';
import { firebaseConfig } from './../environments/firebase.config';
import { AngularFireDatabaseModule } from 'angularfire2/database';
import {PushService} from './push.service';
const appRoutes: Routes = [
{
path: '',
component: FetchApiComponent
},
{
path: '/latest',
component: FetchLatestComponent
},
{
path: '/top',
component: FetchTopComponent
},
{
path :'*',
component: FetchApiComponent
}
];
firebase.initializeApp(firebaseConfig);
#NgModule({
declarations: [
AppComponent,
FetchApiComponent,SidebarComponent, FetchLatestComponent, FetchTopComponent
],
imports: [
RouterModule.forRoot(appRoutes),
BrowserModule, YoutubePlayerModule,
FormsModule,
AngularFireModule.initializeApp(firebaseConfig),
AngularFireDatabaseModule,environment.production ?ServiceWorkerModule.register('firebase-messaging-sw.js'):[],ServiceWorkerModule.register('/firebase-messaging-sw.js', { enabled: environment.production }),
HttpClientModule,environment.production ? ServiceWorkerModule.register('ngsw-worker.js') : [], ServiceWorkerModule.register('/ngsw-worker.js', { enabled: environment.production })
],
providers: [UserService,UserServiceTop,UserServiceLatest,PushService],
bootstrap: [AppComponent]
})
export class AppModule {}
Can you point me in right direction?
You will see in your example url, that once you get the 404 error you can't make it work, but if you include a hash before the angular-specific url like /#latest it will work.
Why stops working when refreshing? your webserver is intercepting the GET request from your browser and is trying to go directly to the directory /latest, which doesn't exist. It doesn't know that it needs to go to /bosv2, find an angular app, and then add the small ending bit to your path which is a not-real directory but a routing for angular. In your local it would work as when you are doing ng serve, webpack webserver is prepared for this, but not the host where you are hosting the app.
By default, angular is using HTML5 style navigation, but with your current webserver settings you would need the old angularjs style (with hash#).
From here, you have two solutions:
Change your webserver configuration
Tell Angular to use HashLocationStrategy (perfectly valid solution), you can go old-school with the HashLocationStrategy by providing the useHash: true in an object as the second argument of the RouterModule.forRoot in the AppModule.
#NgModule({
imports: [
...
RouterModule.forRoot(routes, { useHash: true }) // .../#/latest/
],
...
I would say going the hash style has a couple of downsides, which may not be relevant in your scenario:
It doesn't produce the clean and SEO Friendly URLs that are easier for users to understand and remember.
You can't take advantage of the server-side rendering.
Hope you find this answer helpful :)
To avoid using hashed routes, you must edit your webserver configuration properly, which is the best solution. You just have to configure it so it fallbacks to index.html, which is Angular's bootstrap. Although there is no universal configuration for this, here are some:
Apache
Add a rewrite rule to .htaccess file
RewriteEngine On
# If an existing asset or directory is requested go to it as it is
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
# If the requested resource doesn't exist, use index.html
RewriteRule ^ /index.html
Nginx
Use try_files in your location block
try_files $uri $uri/ /index.html;
IIS
Add a rewrite rule to web.config
<system.webServer>
<rewrite>
<rules>
<rule name="Angular Routes" 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="/index.html" />
</rule>
</rules>
</rewrite>
</system.webServer>
GitHub Pages
You can't configure it directly, but you can add a 404 page. Copy index.html into 404.html in the same directory or add a symlink: ln -s index.html 404.html.
Firebase hosting
Add a rewrite rule.
"rewrites": [ {
"source": "**",
"destination": "/index.html"
} ]
Source: https://angular.io/guide/deployment#server-configuration
With .htaccess you can try with following way also:
<IfModule mod_rewrite.c>
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html
# to allow html5 state links
RewriteRule ^ index.html [L]
</IfModule>
In app.module.ts
import {LocationStrategy, HashLocationStrategy} from '#angular/common';
After import add following line to providers.
{provide: LocationStrategy, useClass: HashLocationStrategy}
ex:
providers: [AuthService,
AuthGuard,
FlxUiDataTable,
{provide: LocationStrategy, useClass: HashLocationStrategy}]
This will solve your issue. Read Documentation here.
Add .htaccess file to your src folder.
.htaccess file
<IfModule mod_rewrite.c>
RewriteEngine on
# Don't rewrite files or directories
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]
# Rewrite everything else to index.html
# to allow html5 state links
RewriteRule ^ index.html [L]
</IfModule>
Load .htaccess file in your build directory dist by adding it to assets in angular.json
"assets": [
"src/favicon.ico",
"src/assets",
"src/.htaccess"
],
I think you are getting 404 because your are requesting http://localhost/route which doesn't exist on tomcat server. As Angular 2 uses html 5 routing by default rather than using hashes at the end of the URL, refreshing the page looks like a request for a different resource.
When using angular routing on tomcat you need to make sure that your server will map all routes in your app to your main index.html while refreshing the page. There are multiple way to resolve this issue. Whichever one suits you you can go for that.
1) Put below code in web.xml of your deployment folder :
<error-page>
<error-code>404</error-code>
<location>/index.html</location>
</error-page>
2) You can also try using HashLocationStrategy with # in the URL for routes :
Try using:
RouterModule.forRoot(routes, { useHash: true })
Instead of:
RouterModule.forRoot(routes)
With HashLocationStrategy your urls gonna be like:
http://localhost/#/route
3) Tomcat URL Rewrite Valve : Re-write the url's using a server level configuration to redirect to index.html if the resource is not found.
3.1) Inside META-INF folder create a file context.xml and copy the below context inside it.
<? xml version='1.0' encoding='utf-8'?>
<Context>
<Valve className="org.apache.catalina.valves.rewrite.RewriteValve" />
</Context>
3.2) Inside WEB-INF, create file rewrite.config(this file contain the rule for URL Rewriting and used by tomcat for URL rewriting). Inside rewrite.config, copy the below content:
RewriteCond %{SERVLET_PATH} !-f
RewriteRule ^/(.*)$ /index.html [L]
Starting with Apache 2.4, you can use the FallbackResource directive instead of rewriting, so it will look like:
FallbackResource /index.html
If you have a different base href (say, /awesomeapp), change it for:
<Location /awesomeapp>
FallbackResource /awesomeapp/index.html
</Location>
If you are using cpanel then it is easy to solve this issue.
Go to Advanced Options
Step 1: Go to Error Pages.
Step 2: Copy your index.html code and paste it in 404.shtml.
That's it technically all your routes are redirected to index.html file. That's what angular wants :) and everything will work normal.
Here are some reference links
Namecheap Error Page Config
Godaddy Error Page config
In my case i did following thing
Method 1 :
in your app.module.ts import below thing
import { HashLocationStrategy, LocationStrategy } from '#angular/common';
#NgModule({
declarations: [...],
imports: [...],
providers: [{provide: LocationStrategy, useClass: HashLocationStrategy}],
bootstrap: [AppComponent]
})
and build with
ng build --base-href /[PROJECT_NAME]/
method 2 :
for nginx,
nano /etc/nginx/sites-available/default
add follwing line in location block
location /[PROJECT_NAME] {
try_files $uri $uri/ /[PROJECT_NAME]/index.html;
}
sudo service nginx restart
and build with
ng build --base-href /[PROJECT_NAME]/
Refetch data on same URL navigation
imports: [RouterModule.forRoot(routes, {
onSameUrlNavigation: 'reload' })],
Make an .htaccess file and add this code; routes will start working:
RewriteEngine On
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR]
RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d
RewriteRule ^ - [L]
RewriteRule ^ /index.html

Remove Question mark in url yii2?

how to remove ? in url yii2?
in rule :
'rules' => [
'<alias:\w+>' => 'site/<alias>',
],
in .htaccess
RewriteEngine on
# If a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward it to index.php
RewriteRule . index.php
Try this set of rules:
'<alias:\w+>/<id:\d+>' => 'site/<alias>',
'<alias:\w+>' => 'site/<alias>',

Url Manager is not working In my yii2 applicatoin

I'm trying to set Url Manager in my yii2 basic template. Below is .htaccess file which is locate mysite.loc/web/.htaccess
Options +FollowSymLinks IndexIgnore
RewriteEngine on
# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# otherwise forward it to index.php RewriteRule . index.php
and inside my web.php file I've added this code snippet:
'urlManager' => [
'class' => 'yii\web\UrlManager',
'enablePrettyUrl' => true,
],
When I'm trying to enter (For example) mysite.loc/index.php/site/movies It comes error like this: 404 not found error nginx
If anybody knows share me please. What's wrong with my settings???
My config
.htaccess
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
config/web.php
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
Try above and go to url mysite.loc/site/movies
I've read several topics and have found correct answer. There is a difference between apache configuration and nginx configuration on setting urlManager.
If Your server Apache (as Vitaly said above):
.htaccess :
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . index.php
config/web.php :
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],
If your server is Nginx:
nginx congfig file (in my case /etc/ngnix/site-enabled/mysite.loc) :
server {
listen 80;
root /var/www/html/mysite.loc/web;
server_name mysite.loc www.mysite.loc;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
As you can see I have added this snippet of code and nothing more :
location / {
try_files $uri $uri/ /index.php?$args;
}
config/web.php file is same as Apache server :
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [
],
],

Yii2 Advance Application Remove '/web' and 'index.php' in frontend and backend

I referred the below given link
Yii2 htaccess - How to hide frontend/web and backend/web COMPLETELY
Remove index.php from url after removing web folder from frontend and backend in yii2
but, i did't get the output
show below URL
localhost/yii2advance/backend/web/index.php?r=site%2Flogin
localhost/yii2advance/frontend/web/index.php?r=site%2Flogin
in above url i remove /web/index.php in both frontend and backend
I get URL like
localhost/yii2advance/backend/site/login
localhost/yii2advance/frontend/site/login
1- put this code in .htaccess flie in yii2advance folder (main folder of project)
# prevent directory listings
Options -Indexes
IndexIgnore */*
# follow symbolic links
Options FollowSymlinks
RewriteEngine on
RewriteRule ^admin(/.+)?$ backend/web/$1 [L,PT]
RewriteRule ^(.+)?$ frontend/web/$1
above code convert
'localhost/yii2advance/frontend/web/index.php'
to
'localhost/yii2advance/'
and it convert
'localhost/yii2advance/backend/web/index.php'
to
'localhost/yii2advance/admin'
2- add this code to frontend/web/.htaccess and backend/web/.htaccess file:
RewriteEngine on
# If a directory or a file exists, use the request directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# Otherwise forward the request to index.php
RewriteRule . index.php
3- in backend/config/main.php put this codes:
'homeUrl' => '/yii2advance/admin',
'components' => [
'request' => [
'baseUrl' => '/yii2advance/admin', // localhost/yii2advance/admin
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [],
],
4- in frontend/config/main.php put this codes:
'homeUrl' => '/yii2advance',
'components' => [
'request' => [
'baseUrl' => '/yii2advance', // localhost/yii2advance
],
'urlManager' => [
'enablePrettyUrl' => true,
'showScriptName' => false,
'rules' => [],
],
Create a ".htaccess" file in the "web" directory with:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]
My pull request was accepted about this. It will be in the 2.0.19 version.

AngularJS HTML5 nested routes

Angular: 1.1.5
I go to: http://xxxxx.com/route1/route2/route3
and /route3 gets triggered instead of route1/route2/route3
Works fine with HTML5 mode off ... :(
Nginx config
location / {
index index.html;
try_files $uri $uri/ /index.html?$args;
}
My app config
$routeProvider.when('/route1/route2/route3', {
templateUrl: '/views/home.html',
controller: 'HomeCtrl'
});
$routeProvider.when('/route3', {
templateUrl: '/views/home.html',
controller: 'HomeCtrl'
});
$locationProvider.hashPrefix('!');
$locationProvider.html5Mode(true);
$location Log:
$$protocol: "http", $$host: "xxxxxx"…}
$$absUrl: "http://xxxxxxx.com/route1/route2/route3"
$$hash: ""
$$host: "10.44.11.73"
$$path: "/route3"
$$port: 80
$$protocol: "http"
$$replace: false
$$url: "/route3"
How can I change my settings to make HTML5 urls working with nested routes?
For single page apps, this is all you need in your NGINX config:
server
{
server_name example.com *.example.com;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
root /var/www/html/example;
index index.html;
location / {
try_files $uri /index.html;
}
}
Add
<base href="/">
to your index.html.