This question already has an answer here:
AngularJS - Enable HTML5 Mode Page Refresh Without 404 Errors [duplicate]
(1 answer)
Closed 4 years ago.
I'm building a web app with Angular 1.x(not using ionic, building a website). I would like to remove the '#' from the URLs. I did implement html5mode true and put a base tag in the head tag in index.html. It works fine until I refresh the pages. When it is in html5mode it thinks that the URL is a request to the server. I'm developing in the local environment with gruntjs using the grunt-contrib-connect plugin and hosting my website in GoDaddy hosting in Linux Hosting Server. I would like to configure the html5mode(removing the hash from the URLs) in both environments(development and production). Note: I'm using ui.router with states if it matters in this problem.
By default, AngularJS will route URLs with a hash(#).
For example:
http://example.com/
http://example.com/#/about
http://example.com/#/contact
To remove the hashtag from the URL, you need to do two things
Configuring $locationProvider
Setting our base for relative links
$location Service
In AngularJS, the $location service parses the URL in the address bar and makes changes to application and vice versa.
$locationProvider and html5Mode
We will use the $locationProvider module and set html5Mode to true.
We will do this when defining Angular application and configuring routes.
angular.module('stackoverflow', [])
.config(function($routeProvider, $locationProvider) {
$routeProvider
.when('/', {
templateUrl : 'partials/home.html',
controller : homeController
})
.when('/about', {
templateUrl : 'partials/about.html',
controller : aboutController
})
.when('/contact', {
templateUrl : 'partials/contact.html',
controller : partialController
});
// use the HTML5 History API
$locationProvider.html5Mode(true);
});
Setting Relative Links
To link around application using relative links, we will need to set a <base> in the <head> of your document.
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<base href="/">
</head>
There are many other ways to configure this and the HTML5 mode set to true should automatically resolve relative links.
Related
This question already has answers here:
Removing # from url in Angularjs while having .run in routes
(7 answers)
Closed 5 years ago.
I am creating an AngularJs application and everything is working fine.
Yet, I am facing an issue trying to remove #!/ from my url
When I run http-server in console it throws
Available on:
http://127.0.0.1:8080
Then I enter there and the url automatically changes to http://127.0.0.1:8080/#!/
I have this in my route provider
.when('/', {
templateUrl: 'galleryMap.html',
controller: 'GalleryMapController'
})
.when('/photo/:id', {
templateUrl: "detail.html",
controller: 'DetailPageController'
})
The I call the url this way
$window.location.href = /photo/3;
$window.location.href = /;
Both don't work unless their urls are written like this http://127.0.0.1:8080/#!/photo/3
http://127.0.0.1:8080/#!/
Is it possible to make it work like a normal url like this
http://127.0.0.1:8080/photo/3
without that horrible tags?
The "horrible tags" are used to indicate routing on the client-side, rather than the server-side. Loading on the client-side allows the page to not need to completely reload in order to load a new page.
However, you can still perform client-side routing without the hash. You should be able to add this to your application's config to remove the hash:
$locationProvider.html5mode(true);
I'm developing an application in .net mvc with angularjs. When I don't use html5 mode it works fine, but when I set html5 mode to true the server calls that address giving me an he resource cannot be found.
This is my app.js
var app = angular.module("myApp", ['ngRoute'])
.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/test',
{
templateUrl: 'templates/TestPage.html',
controller: 'ProfesionalController'
});
$routeProvider.otherwise({ redirectTo: '/' });
$locationProvider.html5Mode(true);
});
And this is my view (layout):
<!DOCTYPE html>
#Scripts.Render("~/bundles/modernizr")
<script src="~/Scripts/angular/angular.js"></script>
<script src="~/Scripts/angular/angular-route.js"></script>
<script src="~/app/app.js"></script>
<script src="~/app/home/home.js"></script>
<script src="~/app/profesional/profesional.js"></script>
<base href="/">
Test
#*this is the link*#
</div>
</div>
</div>
<div ng-app="myApp" class="container body-content">
<div ng-view></div>
#RenderBody()
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
When I click to test link the server try to locate:
http://localhost:39881/test" giving me an 404 Not Found - http://localhost:39881/test"
What I'm missing. It works well with no html5 mode.
Even I was facing the same issue when I was trying to enable html5 mode in my application. Later when I saw the entire code carefully, I came to know the name of my API call and my route call were same. The browser was getting confused and instead of calling route call it was calling the api call.
Try changing either of the name. It should work fine.
You need to configure your server side rewrites so it doesn't try to load up pages at that path. See details for your server type here: https://github.com/angular-ui/ui-router/wiki/Frequently-Asked-Questions#how-to-configure-your-server-to-work-with-html5mode
Something that cost me a lot of time that hopefully will help others if you are using Azure and a pure ng app:
I am using Azure and Angular and hit the same problem. I had the IIS Rewrite rules to redirect all requests to the index.html file as per the documentation in ng.
However, it still was not working on production, only on local. It turned out to be a stupid user error - my Angular webapp is a pure HTML/JS app (ie. no ASP.NET MVC) and the Azure Publishing Profile had not marked the web.config for dpeloyment to the cloud. I used Kudu on Azure to check the webapp and there was no web.config on live, hence the rewrite rules were not being considered... changing it to FileType Content solved the issue so the web.config was deployed correctly and the routing now works..
I am using UI-Router for routes/states in my app and URLs were having "#" so to remove this , I used $locationProvider like -
function configState($stateProvider, $urlRouterProvider, $locationProvider) {
$locationProvider.html5Mode(true);
Added ngRoute in module dependency and added <base href="/" > in my index.html.
Problem -
If I am using it as a normal app like in same tab and navigates to other state, it works BUT whenever I pasted the URL in another tab and hit enter its throwing Cannot GET /app_views/contacts URL is like - http://localhost:9000/app_views/contacts
Though with hash in URL it works in both way manner.
You are likely getting this error because your server is not configured correctly. In other words when you manually enter /app_views/contacts it will make a request to the server for that page. For this to work properly you need configure your server to route all traffic to your index.html page in order for Angular to properly take over and display the correct view.
Here is a related post Reloading the page gives wrong GET request with AngularJS HTML5 mode
I am building an AngularJS application, it works well with hash URL.
If I click on an anchor <a href="#/3125/"> then the URL is updated to http://localhost:8000/app/index.html#/3125/ which is desired.
Now I plan to change the URL to HTML5 mode, so I configured the application with below code
var demoApp = angular.module('demoApp', ['demoResources']);
demoApp.config(['$locationProvider', function($locationProvider) {
$locationProvider.html5Mode(true);
}]);
Unfortunately, this time if I click on the same anchor, I got URL escaped as http://localhost:8000/app/index.html#%2F3125%2F thus the link is broken. However, the expected URL is http://localhost:8000/app/index.html/3125.
Does anyone know why this is not working? I am using Angular 1.2.1
You should add a <base> tag in the <head> section of your application :
<base href="/app"/>
See the "Relative Links" section in the $location documentation.
See also AngularJS subdirectory routing not working, with <base> tag applied
How does angular know to make a request for the template view that contains 'ng-view' element?
If I navigate in my application say directly to
http://localhost/Categories/List/accessories
. A request is still made to '/ or the index template' as this contains the 'ng-view' element needed to render all the views.
When I navigate from the index to /Categories/List/accessories no request is made for the index again.
Below is my basic routing which has been copied in part from the Angular MVC "CookBook" example on GitHub
angular.module('myApp', ['myApp.ctrl.list'])
.config(['$routeProvider', '$locationProvider', function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: '/Home/Splash',
});
$routeProvider.when('/Categories/List/:slug', {
templateUrl: '/Categories/List',
controller: 'listCtrl',
});
$routeProvider.otherwise({
redirectTo: '/'
});
}]);
With your routing configuration, I believe your example url is missing a pound sign (#), so it should look like:
http://localhost/#/Categories/List/accessories
The part after the # sign is the path intended to be resolved by AngularJS (ie. the routing configuration you have defined)
When you enter the above URL into the address bar of the browser, the browser automatically looks for index.html on localhost. Most browsers, if not all, are set to look for index.html when only the domain name is present in the URL.
What about the part after the # sign? You might ask. The path after the # sign does not get sent to the server, by definition, and thus the browser could care less of what that part is consisted of.
In the second scenario you mentioned, AngularJS does not request for index.html because it's been cached the first time it was loaded and that cached copy is used.
Is your locationProvider configured for HTML5?
$locationProvider.html5Mode(true);
See Using HTML5 pushstate on angular.js