PathLocationStrategy vs HashLocationStrategy in web apps - url

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.

Related

check if url can be loaded in an iframe

Snip.ly nicely checks if the entered web address can be used in an iframe.
I'd like to replicate it in ruby. Looking through their code they send an ajax request to their server and thats where they do the validation.
Even after extensive googling couldn't find anything that could help me accomplish that.
My use case is that we let users add news listings to their page, which are shown in iframes, and would like to show it if the entered url can be used in an iframe.
You can figure out some cases by checking the X-Frame-Options header. But as you mentioned in the comments, it does not work all the time.
In my experience, it's best to side-step the problem altogether.
If you reverse-proxy your request through your rails server, then you can display pretty much anything all the time in your iframe.
Following is an example of the process. I'm assuming that your server is your-server.com and the user wants to list a page on user.com/list. The way it works would be:
Set an iframe's src to https://your-server.com/proxy?url=https://user.com/list`
Intercept the request, extract the url: https://user.com/list
Perform an HTTP request on https://user.com/list to fetch the content
Return it to the browser as if it come from your own server
This approach works pretty much all the time, but it then has other limitations:
- you should reverse proxy any asset on that page that has a relative url; otherwise the css/images may be broken
- you must handle ajax requests on that page
You can fix these as well, by transforming the html before step 4.
You could use https://github.com/waterlink/rack-reverse-proxy for step 2 and 3, instead of re-implementing your own reverse proxy.
You could set it up using the following code in config/application.rb:
config.middleware.insert(0, Rack::ReverseProxy) do
reverse_proxy_options timeout: 10 # avoids waiting for pages that take forever to load
reverse_proxy(/proxy\?url=(.*)/, '$1') # reverse proxy on the url parameter
end

Angular dart bookmarking views

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.

Block an undesirable proxy from accessing a Rails 2.3.15 app on Heroku

I'm looking for a way to block a specific proxy, for example this one:
http://demosites.conversionsupport.com/reverseproxydemo?domainpath=http://stackoverflow.com
I don't want it accessing/displaying my rails 2.3.15 app on Heroku. I've played with the gems rack-rewrite and rack-block, but had no luck going that route because I need to block by domain name, not IP address (the thing is hosted on ghs.google.com, which I'd rather not block)
In a perfect world I could redirect to my canonical URL, but I'd also settle for a 503 or a 404.
(The reverse-proxy in question is used to show off the proxy owner's chat widget app, but on any website, instead of restricting use to sites owned by the proxy owner's potential clients. It also causes some nasty crawl bot errors to be logged in google's web master tools. That in and of itself isn't a big deal, but when coupled with that breaking-the-site-functionality thing, and the fact that my site has a Creative Commons license which requests the site not be reused for commercial purposes, it makes me want to put a stop to it.)
Rack::Attack!!! seems quite thorough. I has support for blacklisting, which sounds like what you need. It doesn't mention Rails 2.3 support, but you can configure it directly using your config.ru regardless.
The example given in the README, shows this
Rack::Attack.blacklist('block bad UA logins') do |req|
req.path == '/login' && req.post? && req.user_agent == 'BadUA'
end
It looks like the Rack request (req) object is passed to the block so you should be able to use any of the methods available on that object.
Since none of the gems we mentioned above can be used with rails 2.3.15 (which I've since updated to 2.3.18), and I don't have the time to do the arduous upgrade from rails 2 to rails 3, I ended up going with the solution below. (Note: this solution only applies to pages served from /app. It does not apply to pages served from /public. I'm still looking for a solution to protecting the pages served from /public.)
I dropped the bits of code below into /app/controllers/application_controller.rb
1.2.3.* is a placeholder for the block of IP addresses that I'm actually blocking. Replace 1.2.3 with the first three octets of the 0/24 range that you want to block, or replace 1.2.3.* with a single ip address to block a single IP. You'll also want to replace http://YourCanonicalDomain.tld/503.html with the address of your 503 page, or other page you want to send users to so they can view your page at the URL it was meant to be displayed at, instead of leaving them at the reverse proxy's URL:
before_filter: block_ip
then later in the file:
def block_ip
if request.remote_ip.match('1.2.3.*')
redirect_to "http://YourCanonicalDomain.tld/503.html"
return
end
end
My 503.html, which resides in /public, displays a note to the user that they're trying to view content in a way that is not allowed, and that they'll shortly be redirected to the homepage for the site. The 503.html contains this within the :
<meta http-equiv="REFRESH" content="15;url=http://YourCanonicalDomain.tld">
Replace http://YourCanonicalDomain.tld with the page you want to redirect users to. Raise or lower the number 15 to raise or lower the amount of time the page is displayed before the user is redirected.

avoiding iframes, but having some iframe like activity in Rails

I have two sites, my main site and a help site with documentation. The main site is rails but the other is simple a wordpress like blog. Currently I have it being pulled into the main site with an iframe, but is there a good way to pull in the html from the other site as some sort of cross-domain (sub-domain actually) partial? Or should I just stick with what works?
If the data sources were all on the same domain, you would be able to utilize straight AJAX to fetch your supplemental content and graft it onto your page. But, since the data is from different domains, the same origin security policy built into web browsers will prevent that from working.
A popular work around is called JSONP, which will let you fetch the data from any cooperating server. Your implementation might look something like this (using jQuery):
$.getJSON(
"http://my.website.com/pageX?callback=?",
function(data) {
$("#help").append(data)
}
)
The only hitch is that the data returned by your server must be wrapped as a javascript function call. For example, if your data was:
<h1>Topic Foo</h1>
Then your server must respond to the JSONP request like this:
callbackFunction("<h1>Topic Foo</h1>")

Resource for Recognizing Framework/CMS From URL or Other Clues?

I'm curious to know which web framework or content management system a website is using based upon clues from the URL, headers, content. Does anyone know of a resource on the web that would provide this? For example:
.html -> maybe a flat-file
.php -> something built using PHP, perhaps.
.jsp -> something using Java Server Pages
.asp -> Active Server Pages
0,2097,1-1-1928,00 -> Vignette CMS
.do -> ??
Thanks.
Finding CMS by url
http://2ip.ru/cms/
enter URL in center input field and click big blue button below
Results in black - not found,
in red - found
NOTE:
May play around with url path: with http://, with or without www. part -- results may differ.
If you're not restricted to just the query string then there are a few other options. For example to identify a rails app:
Script, stylesheet and image tags tend to have a 10 digits number appended (this allows you to cache, and still change the file):
<script src="/javascripts/all.js?1236037318" type="text/javascript"></script>
You can also sometimes tell from the cookies what the framework is. For example rails apps tend to have a session cookie called _appName_session, and often you can find a flash contained.
You're on the right track with your list there. If all you want to know is the stack (LAMP, IIS, Java) then that's all you really need.
If querying the URL in question is an option, then you can usually pull the webserver make/version out of the HTTP response header as well.
There is a nifty Chrome extension called Wappalyzer:
Wappalyzer is a browser extension that uncovers the technologies used
on websites. It detects content management systems, eCommerce
platforms, web servers, JavaScript frameworks, analytics tools and
many more.

Resources