var app = angular.module("myApp", ["ngRoute","ui.router"]);
app.config(function($routeProvider,$urlRouterProvider,$locationProvider,$provide, $stateProvider) {
$routeProvider
.when("/", {
templateUrl : "templates/main.htm"
})
.when("/london", {
templateUrl : "templates/london.htm",
controller:"ctrl"
})
.when("/paris", {
templateUrl : "templates/paris.htm"
});
$locationProvider.html5Mode(true);
});
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Bootstrap Example</title>
<base href="/simpleAnjularjs/" />
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</head>
<body ng-app="myApp">
<!-- routeProvider -->
Red
Green
<div ng-view></div>
<!-- stateProvider -->
<!-- <a ui-sref="red">Red</a>
<a ui-sref="green">Green</a>
<div ui-view></div> -->
<!-- <script src="js/angular.min.js"></script> -->
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>
<!-- <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular-route.js"></script> -->
<script src="node_modules/angular-route/angular-route.js"></script>
<script src="js/Angularjs_ui_routing.js"></script>
<script src="app.js"></script>
</body>
</html>
where other templates(london.html,paris.html,main.html) used are normal html pages with a default tag and when i reload any of the pages i'm getting an error saying "The requested URL /simpleAnjularjs/paris was not found on this server"
How to: Configure your server to work with html5Mode
When you have html5Mode enabled, the # character will no longer be used in your urls. The # symbol is useful because it requires no server side configuration. Without #, the url looks much nicer, but it also requires server side rewrites.
Apache Rewrites
<VirtualHost *:80>
ServerName my-app
DocumentRoot /path/to/app
<Directory /path/to/app>
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]
</Directory>
</VirtualHost>
Azure IIS Rewrites
<system.webServer>
<rewrite>
<rules>
<rule name="Main Rule" 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>
Related
I have a react application with the following files and folders:
├── static
│ ├── css
│ │ └── someCssFile.css
│ ├── js
│ │ └── someJsFile.js
├── index.html
├── web.config
The web.config file is as following:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<!-- This part is responsible for URL rewrites -->
<rewrite>
<rules>
<rule name="DynamicContent">
<conditions>
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="True"/>
</conditions>
<action type="Rewrite" url="index.html"/>
</rule>
</rules>
</rewrite>
</system.webServer>
</configuration>
And the index.html file is as
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,shrink-to-fit=no">
<meta name="theme-color" content="#000000">
<link rel="manifest" href="/manifest.json">
<link rel="shortcut icon" href="/favicon.ico">
<title>React App</title>
<link href="/static/css/main.8833e8af.css" rel="stylesheet">
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<script type="text/javascript" src="/static/js/main.8f22fc15.js"></script>
</body>
</html>
I have also installed the URL Rewrite. But when deploying the app on the ISS, it does not work!
Could you please help me with the problem?
Your action url needs to be a fully qualified url. E.g.
<action type="Redirect" url="https://{HTTP_HOST}/index.html"/>
{HTTP_HOST} is replaced by IIS with the actual hostname in the request. You may want to hardcode your actual domain if you have several domains/ redirects pointing at the same site.
How to host server side rendering application which developed in react js. Now I want to deployed in IIS. So, how can I achieve this.
anyone suggest any example.
Please help me.
You still need to have node.js on your server. IIS will just proxy your app.
There is different ways how to achieve that:
With IISNode project:
Instructions you can find here:
http://www.amazedsaint.com/2011/09/creating-10-minute-todo-listing-app-on.html
With ARR(Application Request Routing) module for IIS:
Instructions you can find here: https://adamtuttle.codes/blog/2015/add-node-to-existing-iis-server/
Install IIS node:
x64 - [https://github.com/azure/iisnode/releases/download/v0.2.21/iisnode-full-v0.2.21-x64.msi)
Install URL rewrite module.
Create Web.config with following declarations in <configuration>/<system.webServer>:
<handlers>
<add name="iisnode" path="server.js" verb="*" modules="iisnode" />
</handlers>
<rewrite>
<rules>
<rule name="Server-side rendering" stopProcessing="true">
<match url=".*" />
<conditions logicalGrouping="MatchAll">
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
</conditions>
<action type="Rewrite" url="server.js" />
</rule>
</rules>
You can optionally exclude node_modules so they are not served by IIS:
<security>
<requestFiltering>
<hiddenSegments>
<add segment="node_modules" />
</hiddenSegments>
</requestFiltering>
</security>
Create node.js server, for example with express.js:
import express from 'express'
const app = express()
app.get('*', (req, res) => {
/render app here/
});
app.listen(process.env.PORT);
Remember to bind to process.env.PORT as it is passed to your server by the IIS!
Render your app server side, for example like this:
const App = ({message}) => <div>Hello {message}</div>
const template = ...
(StackOverflow eats my tags embedded in js... so copy that and use string interpolation)
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
</head>
<body>
<div id="app">${body}</div>
</body>
<script async src="/bundle.js"></script>
</html>
import { renderToString } from 'react-dom/server'
const renderedComponent = renderToString(<App message={`from ${req.url}`} /> )
const html = template(renderedComponent)
res.send(html)
Configure your build tool and router.
You can create two separate build targets for the Webpack - one for the client and one for the server. You should also handle in-app routing but that depends on what library you are using.
I am trying to run Angular 4 on Apache 2 on Fedora 25.
$ ng build --prod --bh /root/beans3/dist/
Produces the dist directory as expected. Next I pointed the Apache to that directory in
/etc/httpd/conf/httpd.conf (all the comments have been removed),
ServerRoot "/etc/httpd"
Listen 139.162.199.9:80
Include conf.modules.d/*.conf
User apache
Group apache
ServerAdmin root#qqiresources.com
ServerName www.qqiresources.com:80
<Directory />
AllowOverride none
Require all granted
</Directory>
DocumentRoot "/root/beans3/dist"
<Directory "/root/beans3">
AllowOverride All
Require all granted
</Directory>
<Directory "/root/beans3/dist">
Options Indexes FollowSymLinks
AllowOverride None
Require all granted
</Directory>
<IfModule dir_module>
DirectoryIndex index.html
</IfModule>
<Files ".ht*">
Require all denied
</Files>
ErrorLog "logs/error_log"
LogLevel warn
<IfModule log_config_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
<IfModule logio_module>
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
</IfModule>
CustomLog "logs/access_log" combined
</IfModule>
<IfModule alias_module>
ScriptAlias /cgi-bin/ "/var/www/cgi-bin/"
</IfModule>
<Directory "/var/www/cgi-bin">
AllowOverride None
Options None
Require all granted
</Directory>
<IfModule mime_module>
TypesConfig /etc/mime.types
AddType application/x-compress .Z
AddType application/x-gzip .gz .tgz
AddType text/html .shtml
AddOutputFilter INCLUDES .shtml
</IfModule>
AddDefaultCharset UTF-8
<IfModule mime_magic_module>
MIMEMagicFile conf/magic
</IfModule>
EnableSendfile on
Theses config settings tell Apache to server the index.html at /root/beans3/dist
Restarting the server with,
$ systemctl restart httpd
Navigating to 139.162.199.9 I can see that Apache is running the index.html file in /root/beans/dist
However the other files in that directory as not being found. This is strange since they are in the same directory as index.html
/root/beans3/dist/index.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Beans3</title>
<base href="/root/beans3/dist/">
<meta charset="utf-8">
<meta http-equiv="x-ua-compatible" content="ie=edge">
<title></title>
<meta name="description" content="">
<!--<meta name="viewport" content="width=device-width, initial-scale=1"> -->
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<!-- <link rel="apple-touch-icon" href="apple-touch-icon.png"> -->
<!-- Place favicon.ico in the root directory -->
<!-- <link rel="stylesheet" href="css/normalize.css"> -->
<!--<!– Latest compiled and minified CSS –>-->
<!-- <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous"> -->
<!-- <link rel="stylesheet" href="css/main.css"> -->
<!-- <script src="js/vendor/modernizr-2.8.3.min.js"></script> -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link href="styles.604a57bc7d4c0f84e447.bundle.css" rel="stylesheet"/></head>
<body>
<script>
window.__theme = 'bs4';
</script>
<app-root>Loading...boo ya!</app-root>
<script src="https://code.jquery.com/jquery-1.12.0.min.js"></script>
<script>
// window.jQuery || document.write('<script src="js/vendor/jquery-1.12.0.min.js"><\/script>')
</script>
<!-- <script src="js/plugins.js"></script> -->
<!-- <script src="js/main.js"></script> -->
<script type="text/javascript">
</script>
<!-- <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>-->
<!-- <script async src="https://maps.googleapis.com/maps/api/js?key=AIzaSyDNjfWKTRj_IlQ6nPTSXDeKKM7yoEnauNI&callback=getLocation"></script> -->
<script type="text/javascript" src="inline.df954263324e7c133385.bundle.js"></script><script type="text/javascript" src="polyfills.a3e056f914d9748ff431.bundle.js"></script><script type="text/javascript" src="vendor.244ceb2ee1e4bb317079.bundle.js"></script><script type="text/javascript" src="main.47083d1d3073f3856af7.bundle.js"></script></body>
</html>
the issue is in index.html <base>
please change <base href="/root/beans3/dist/"> to <base href="/">
since you are setting the DocumentRoot in your config to that path.
or remove -bh <path> and just use ng build --prod
I am having a lot of issues routing my pages with Spring-Boot and AngularJS. Once the index.html page renders I get a 404 error when I click on a new link. AngularJS in loading fine, and the controllers etc are also loading.
Also worth noting I have to use this <base href="/"> when I run it on my IDE and this <base href="/personalsite/"> when I package it into a war file on deploy it on tomcat.
index.html
<html lang="en" ng-app="SharpVision">
<head>
<base href="/">
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Drew</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta name="Drew's personal site" content="Drew" />
<meta name="author" content="AHthemes" />
<!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->
<!-- WARNING: Respond.js doesn't work if you view the page via file:// -->
<!--[if lt IE 9]>
<!--<script src="http://a1alfred.com/sharpvisionbs3/v2/angular/assets/libs/html5shiv/html5shiv.min.js"></script>-->
<!--<script src="http://a1alfred.com/sharpvisionbs3/v2/angular/assets/libs/respond/respond.min.js"></script>-->
<![endif]-->
<!--[if gte IE 9]>
<style type="text/css">
.gradient {
filter: none;
}
</style>
<![endif]-->
<link href="assets/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<link href="assets/css/styles.css" rel="stylesheet">
</head>
<body>
<ng-include src="'views/structure/navigation.tpl.html'"></ng-include>
<ng-view autoscroll="true"></ng-view>
<ng-include src="'views/structure/footer.tpl.html'"></ng-include >
<!--Scripts-->
<!--<script src="bower_components/masonry/dist/masonry.pkgd.min.js"></script>-->
<!--<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>-->
<script src="assets/libs/flexslider/jquery.flexslider.js"></script>
<script src="assets/libs/masonry/masonry.pkgd.min.js"></script>
<script src="assets/libs/imagesloaded/imagesloaded.pkgd.min.js"></script>
...
app.config
app.config(function($routeProvider, $locationProvider){
$routeProvider.when('/',{
templateUrl: "views/misc/home.tpl.html",
controller: "HomeController"
})
.when('/features/blog',{
templateUrl: "views/features/blog.tpl.html",
controller: "BlogController"
})
.when('/features/blogpost',{
templateUrl: "views/features/blog-post.tpl.html",
controller: "BlogPostController"
})
.when('/features/portfolio',{
templateUrl: "views/features/portfolio.tpl.html",
controller: "PortfolioController"
})
.when('/features/portfolioitem',{
templateUrl: "views/features/portfolio-item.tpl.html",
controller: "PortfolioItemController"
})
.when('/features/gallery',{
templateUrl: "views/features/gallery.tpl.html",
controller: "GalleryController"
})
.when('/features/404',{
templateUrl: "views/features/404.tpl.html",
controller: "404Controller"
})
.when('/features/500',{
templateUrl: "views/features/500.tpl.html",
controller: "500Controller"
})
.when('/contact',{
templateUrl: "views/misc/contact.tpl.html",
controller: "ContactController"
})
.otherwise({redirectTo:'/'});
$locationProvider.html5Mode(true);
});
Once the page loads I select gallery:
at: http://localhost:8080/features/portfolioitem
which give me a 404:
However all this ONLY happens when I create a war file and deploy it on Tomcat. On my intellij IDE all I have to do it change <base href="/personalsite/"> to <base href="/"> and it works fine.
It appears once the application starts loads everything fine but handles the routing through Spring's #RestController so I tried this:
//try mapping to contact and gallery and see what happens
#RequestMapping(value = "/features/portfolioitem", method = RequestMethod.GET)
public String galleryPage(){
System.out.println("HIT HIT HIT HIT HIT!!!");
return "personalsite/features/portfolioitem";
}
galleryPage() renders a page but just the String personalsite/features/portfolioitem on the page.
---------------------------UPDATE 1------------------------------------
I decided to see if I could use Spring-boot `#RestController` to route my pages but that was unsuccessful. This is how I did it:
//try mapping to contact and gallery and see what happens
#RequestMapping(value = "/features/portfolioitem", method = RequestMethod.GET)
#ResponseBody
public String galleryPage(){
System.out.println("HIT HIT HIT HIT HIT!!!");
return "views/features/portfolioitem";
}
#RequestMapping(value = "/", method = RequestMethod.GET)
#ResponseBody
public String indexPage(){
System.out.println("I be in here too");
return "index";
}
WebConfig.java
#Configuration
public class WebConfig extends WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter{
private static final Logger LOGGER = Logger.getLogger(WebConfig.class);
#Bean
InternalResourceViewResolver internalResourceViewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/webapp/");
viewResolver.setSuffix(".html");
return viewResolver;
}
#Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer){
configurer.enable();
}
}
This this only renders the string of whatever the method returns and Angular doe not load.
---------------------Update 2----------------------------
<?xml version='1.0' encoding='utf-8'?>
<Server port="8005" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<!-- Security listener. Documentation at /docs/config/listeners.html
<Listener className="org.apache.catalina.security.SecurityListener" />
-->
<!--APR library loader. Documentation at /docs/apr.html -->
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<!-- Prevent memory leaks due to use of particular java/javax APIs-->
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<!-- Define an AJP 1.3 Connector on port 8009 -->
<Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
<Engine name="Catalina" defaultHost="localhost">
<Realm className="org.apache.catalina.realm.LockOutRealm">
<!-- This Realm uses the UserDatabase configured in the global JNDI
resources under the key "UserDatabase". Any edits
that are performed against this UserDatabase are immediately
available for use by the Realm. -->
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
<Host name="localhost" appBase="webapps"
unpackWARs="true" autoDeploy="true">
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
--------------------Update 3------------------------------
I added server.contextPath=/personalsite/ to my application.properties
I then change <base href="/"> to this is good because now my IDE is doing the same thing as tomcat. Index.html will render athttp://localhost:8081/personalsite/#/BUT once I click a link I get a blank page, for examplehttp://localhost:8081/features/portfolioitembutpersonalsite` is missing from the path. I add that and I get the following page:
Update 1:
You should add 'server.contextPath=/' to your 'application.properties' file.
Update 2:
You need to remove the #ResponseBody annotation if you want Spring to resolve your view, rather than return a string, from your galleryPage method.
Update 3:
If your entire application is a single page application, with embedded templates, and you want your application, when refreshed on any valid path (like '/features/portfolioitem') to render index.html, you need to route every request to your index method. Try this:
#RequestMapping(value = "/**", method = RequestMethod.GET)
public String indexPage(){
System.out.println("I be in here too");
return "index";
}
This should load your index.html for all URLS. It is then up to your application to determine if the URL is valid.
Also, make sure you have $locationProvider.html5Mode(true); set in your app.
Using ui-router with AngularJS application, It don't render the views correctly.
That's the app.js file implementation:
'use strict';
angular.module('myApp', [
'ngCookies',
'ui.router'
]);
angular.module('myApp').config(['$stateProvider', '$urlRouterProvider', '$locationProvider', '$httpProvider',
function($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider){
// Login Route
$stateProvider.state('login', {
url: '/login',
templateUrl: '/app/views/login.html',
controller: 'loginController'
});
$stateProvider.state('home', {
url: '/home',
templateUrl: '/app/views/home.html'
});
$urlRouterProvider.otherwise('/home');
$locationProvider.html5Mode(true);
}]);
And that's the index.html:
<!DOCTYPE html>
<html class="no-js" lang="en" data-ng-app="myApp">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="./vendor/bootswatch/bootstrap.css" media="screen">
<link rel="stylesheet" href="./vendor/bootswatch/bootswatch.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css">
<link rel="stylesheet" href="./css/style.css">
<script src="./bower_components/angular/angular.min.js"></script>
<script src="./bower_components/angular-route/angular-route.min.js"></script>
<script src="./bower_components/angular-cookies/angular-cookies.min.js"></script>
<script src="./bower_components/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="./app/app.js"></script>
<script src="./app/modules/login/module.js"></script>
<script src="./app/modules/home/module.js"></script>
</head>
<body data-ng-cloak>
<div class="container" data-ui-view></div>
<script src="./vendor/jquery/jquery-1.10.2.min.js"></script>
<script src="./vendor/bootstrap/js/bootstrap.min.js"></script>
<script src="./vendor/bootswatch/bootswatch.js"></script>
</body>
</html>
The problem is that when starting the app and passing to the browser this url (localhost:8000/login) or (localhost:8000/home), It responds with (Not Found)
The cause of this problem is that the URL don't contain the '#'.
Example:
[localhost:8000/#/home] --> works well
[localhost:8000/home] --> don't work at all and shows "Not Found"
The problem is with your .html5Mode(true). You need to update your .htaccess. It all depends on your application, but here is an example of what you can do. This has worked for many Apache users, so hopefully, it will work for you as well.
You also need to take care of the the known <base href> bug found here
<VirtualHost *:80>
ServerName my-app
DocumentRoot /path/to/app
<Directory /path/to/app>
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]
</Directory>
</VirtualHost>
Source: This post.