It is my experience that Angular Dart is agnostic to your backend server implementation. it doesn't care if your server is in java, ruby or whatever. Angular dart has the concept of views and has a module that deals with routing between them. these routes also modify the address bar of the browser when it changes views.
I have come across this issue. Though the angular router module will change the address bar, because said route doesn't actually exist as far as the backend server is concerned, and as such will always issue a 404 response.
If such is the case, then I find the ability to route to different pages via angular to be pointless. Might as well I code in a more traditional server oriented fashion to transition between pages, than to sue angular.
Is it that there is something that is missing? Is there a way you can can get your server to resolve to the correct angular page?
You can use usePushState: false then only the (client) local part of the URL is changed.
see https://github.com/angular/angular.dart.tutorial/blob/master/Chapter_06/web/main.dart#L27
This part after the hash is never sent to the server.
This might cause some additional work for SEO.
http://example.com/index.html#someRoutePath/anotherRoutePath
or you can configure your server in a way that each request is handled independent of the path in the request and use the route package server side too.
see also https://stackoverflow.com/a/17909743/217408
You can configure your backend server to point all routes to the same file (using some kind of wildcard route which all decent servers should support). So app/some/page and app/another/page would both be served app.html. Then on your app startup you could have Angular parse the URL of the page, and manually route to that page.
I have used this approach with a Polymer app (with the Route library) and it works great. It should work similarly for Angular.
Related
We're breaking our monolithic Rails application in to microservices. Our services are hosted on AWS and are behind ALBs. We cannot use host based routing as we are multi-tenant via subdomain, and it would be an SSL nightmare to maintain the required certs for each tenant/environment/service combination. So we are using path-based API routing with rules on the load balancer. A request looks like this:
Client -> www.example.com/api/:service_name/the_rest_of_the_path -> ALB -> route to rails service by name of :service_name
Because ALB cannot modify the path of a request before it sends it on to the serive, when it reaches the Rails services the path is still /api/:service_name/the_rest_of_the_path . This means in order to route to the proper controllers/actions in this case, we'd need to actually create a rails scope on namespace of /api/:service_name . This would work in theory but it has two drawbacks.
Firstly it means local developers have to deal with ALB/client specific concerns -- the path used for external service/cluster routing for ALB.
The second is that it couples the application to that path. If the load balancer decided the path should be /:service_name/the_rest_of_the_path instead then it would mean changing the application code in conjunction with the load balancer rules to accommodate it. It's not optimal and I'd prefer to avoid it if at all possible.
I thought then perhaps we could introduce a webserver to the mix, in between the load balancer and the application layer. I worked on a proof of concept for this and had it stripping out /api/:service_name before it got to the service -- leaving the Rails app with just "the_rest_of_the_path" which is all it cares about. Great! Perfect! Or so I thought.
It works well enough to route initial requests to, It however falls flat when any sort of redirects or links are used by taking the current path (as Rails sees it) in to consideration.
In the event /api/:service_name is stripped off before it hits the service, any subsequent links or redirects made from the Rails server itself naturally do not include it in there any longer. You may be on www.example.com/api/:service_name/foo/bar but Rails only thinks you're at /foo/bar. When it tries to tack something on to the path for a redirect or link like /foo/bar/baz, it loses the thing that identifies what service to send it to so the route dies at the load balancer.
This has particularly been an issue with Omniauth/Oauth2 flows for us. Omniauth wants to live at /auth/:provider by default. If the request path is actually /api/:service_name/auth/:provider then it won't match and the Oauth flow wont initiate. Further if there is a failure with the Oauth flow, Omniauth will hard redirect to www.example.com/auth/failure -- which of course does not resolve as the LB does not know where to route the request to.
If we provide a path_prefix to Omniauth as /api/:service_name/auth then it wont match when testing locally at /auth and it won't initiate the flow there.
We won't have control over all of the gems we use and where they redirect to so my question is: Is there a proper way of hanging Rails API microservices off a path on a load balancer, and not have to pull teeth to preserve the necessary prefix in all routes and links and redirects? Something that is essentially a global base href that we can set there, but not set locally so that we can continue to develop at localhost:3000/path instead of remembering to use (and coupling with) an LB path like localhost:3000/api/:service_name/path ?
I have a simple web server running Windows 2012 with IIS. I have half a dozen domains linked to this server that are basically not in use yet. I have a few more domains which are used but they could all have various subdomains that aren't supported by any site yet. So I have a default site in IIS set to catch all incoming requests that aren't handled by any other site on the server or any other server. And it's main purpose is to show a "Page not in use yet" message.
That's easy to set up but I want these pages to be a bit more fancy. So I want to have some kind of routing based on the domain name so example.com and sub.example.com and sub.sub.example.com would all be handled by the same view, but anotherexample.com would be handled by a different view and thirdexample.com by yet another view. And any domain that is not caught by this routing system would go to the default view.
And I wonder if there's a simple way to do this. Something like [route("example.com")] as a controller attribute which the system would recognize as the controller for a specific domain and it's subdomains. (And the URL path can be ignored.) I don't know if something like this already exists and have used Google but found nothing yet.
I can create a custom route, of course. But this tends to result in an if-then-else situation for all potential domain names. I need to know if there's a better method.
Use the URL rewrite module for IIS:
https://learn.microsoft.com/en-us/iis/extensions/url-rewrite-module/using-the-url-rewrite-module
What are the pros and cons of using:
PathLocationStrategy - the default "HTML 5 pushState" style.
HashLocationStrategy - the "hash URL" style.
for instance, using HashLocationStrategy will prevent the feature of scrolling to an element by its #ID, but some 3rd party plugins require the HashLocationStrategy or the Hashbang #! in order to work in ajax websites.
I would like to know which one offers more for a webapp.
For me the main difference is that the PathLocationStrategy requires a configuration on the server side to all the paths configured in #RouteConfig to be redirected to the main HTML page of your Angular2 application. Otherwise you will have some 404 errors when trying to reload your application in the browser or try to access it using a particular URL.
Here is a question that could give you some hints about this:
When I refresh my website I get a 404. This is with Angular2 and firebase.
Hope it helps you,
Thierry
# can only be processed on the client, the servers just ignore them. This can cause problems with search engines (SEO), redirects can cause redundant page reloads.
This page https://github.com/browserstate/history.js/wiki/Intelligent-State-Handling has some detailed explanation, while some of the arguments don't apply for Angular applications (for example - doesn't work with JS disabled).
The "disadvantage" of HTML5 pushstate is that is requires server support like explained by Thierry.
According to official docs:
When the router navigates to a new component view, it updates the browser's location and history with a URL for that view. This is a strictly local URL. The browser shouldn't send this URL to the server and should not reload the page.
PathLocationStrategy
Modern HTML5 browsers support history.pushState, a technique that changes a browser's location and history without triggering a server page request. The router can compose a "natural" URL that is indistinguishable from one that would otherwise require a page load.
Here's the HTML5 pushState style URL that routes to the xyz component: localhost:4200/xyz/
HashLocationStrategy
Older browsers send page requests to the server when the location URL changes unless the change occurs after a # (called the hash). Routers can take advantage of this exception by composing in-application route URLs with hashes.
Here's a hash style URL that routes to the xyz component: localhost:4200/src/#/xyz/
I would like to know which one offers more for a webapp.
Almost all Angular projects should use the default HTML5 style as:
It produces URLs that are easier for users to understand.
It preserves the option to do server-side rendering later.
Rendering critical pages on the server is a technique that can greatly improve perceived responsiveness when the app first loads. An app that would otherwise take ten or more seconds to start could be rendered on the server and delivered to the user's device in less than a second.
This option is only available if application URLs look like normal web URLs without hashes (#) in the middle.
Stick with the default unless you have a compelling reason to resort to hash routes.
I'm working on a project to require HTTPS everywhere among a suite of MVC and WebAPI applications. I'm trying to understand the trade-offs between clicking the "Require SSL" checkbox in IIS & using a URL Rewrite zmodule vs. using a RequireHttpsAttribute in my global filters and modifying my web.config.
I've found the following guides detailing each approach:
https://webmasters.stackexchange.com/questions/28057/iis-7-require-ssl-automatically-redirect-to-https
http://tech.trailmax.info/2014/02/implemnting-https-everywhere-in-asp-net-mvc-application/
Explain the mechanism can be lengthy, so I will just list the most significant differences in behaviour:
do "Require SSL" in IIS:
The context basically expalin what it do, it's "Require" not "Enforce", which means, if people trying to access your website content through http, the server will just respond with a 403 error, which is usually not a desired behavior, but this may help some certain situation
using URL rewrite module:
The module itself can do quite some different thing, but I assume you are just going to do the regular https redirect. Which means, if user trying to hit ANY content of the site through http, the server will do a 301 or 302 redirect to the https version of same url. This is usually a good option since it doesn't affect any usability of the website.
Global RequireHttpsAttribute action filter: This do similar thing to option number 2, it will do a 302 redirect for any http request that is hitting an ACTION. The main difference is that this only applies to all actions in your controllers, Which means, if someone trying to just get a image or css file through http on your website, this option will let it through and not do any enforcement. This leave you the capability to serve static contents through http, which can be useful in some specific circumstances
Just one extra thing worth mention, the 301 and 302 redirect is not going too well with http POST, so if your user trying to do a post through http, the request body will get lost (thanks to the info from #ChrisPratt).
Typically the folks managing the infrastructure are responsible for making sure things are on https. Typically they aren't very good at this so that is where the RequireHttpsAttribute kicks in as it can encforce https requests at a code level thereby enforcing the HTTPS-only attribute.
In practice it isn't so great as many production setups -- including stackoverflow.com's -- see https terminated in an edge device before being unwrapped and handed to the back-end apps as http and the require https attribute isn't quite nuanced enough to understand this distinction.
The best bet in general is to configure the edge device providing the public http interface to take HTTPS and only HTTPS. Then setup secondary virtual sites [or whatever is vendor appropriate] to redirect all traffic to the cannonical HTTPS url. I'd be a bit nervous about relying upon the RequireHttpsAttribute unless it will be a small app handling it's own requests. That still leaves open holes in terms of artifacts and other things that might not be coming off of a controller.
I am trying to implement the Jonathon Kresner
"Asp .net Mvc 4 Proxy Server/Controller (For help with Cross Domain Request)" https://gist.github.com/jkresner/3982746 .
Could anyone indicate how to call it from jquery please?
the coffescript call with the article gist.github.com/jkresner, leaves me perplexed.
The coffeescript basicaly says that for clients who can't connect to the remote url by themselves, swap out the specified remote URL reference (i.e. http://api.othersite.com/Widget/7 ) with a reference to http://myoriginalpagehost.com/proxy and let the server side proxy the content from the http://myoriginalpagehost.com/proxy URI over to the http://api.othersite.com/Widget/7 URL.
One thing to note on that proxy is that it appears that cache control mechanisms will likely be subverted causing a potentially significant system load. Something to think about before boilerplate copy / paste of someones code. :-/
This article discusses another solution to the proxy issue that makes use of IIS's URL rewriting mechanisms. No coding, just configuring.