I'm working on a Ember.JS app using
App.Router.reopen({
location: 'hash'
});
Which means that all my URLs are something like these:
http://example.com/#/
http://example.com/#/abc
http://example.com/#/def/ghi/123
The issue:
In a very specific case, the user will try to access my application using:
http://example.com/abc (yes, without the hash)
My question:
Is it possible to redirect this user from:
http://example.com/abc
to
http://example.com/#/abc
using the router.js file or a similar approach such as use .htdocs in a PHP app to redirect URLs?
Unless the webserver actually serves the Ember App when visiting example.com/abc, there is nothing you can do from the Ember side, because the code never gets to execute.
Thank all for the help!!
Here it is how I solved the issue:
We just added a redirect in the Nginx server. In case you use apache, you can also do that on its configuration.
location /abc {
rewrite ^.* http://example.com/#/abc redirect;
}
Related
Is it possible to serve a dynamic html page without a backend server or without using a front-end framework like Angular?
Edit
To clarify, the index file is served from a backend. This question is about how to handling routing between the index and dynamic pages.
I have an application that consists of two files - index.html and dynamic.html. When the user clicks an option say "Option A", they are served dynamic.html and the url is updated to /option-a. Now, with a server this is no problem and assuming the user visits the app from the landing page, it isn't a problem either because a cookie can be set. However, suppose a user visits a page at my-domain/option-a. That route doesn't exist and there is no server to redirect so it will 404. They would have to visit dynamic.html.
I think this architecture demands that there's either a server to handle route redirects or a SPA framework.
Is there something I'm missing?
your SPA framework will be active only once your HTML page is loaded and to do that you need to redirect any URL that user tries for your domain to that HTML file. For this you obviously need a server (and since you are talking about my-domain/option-a I assume you have atleast a basic server). You can refer to this link to get an idea on how server can redirect a URL to specific html file: Nodejs - Redirect url.
Once HTML is loaded you can initialize your SPA framework and decide the template to be loaded based on the URL.
Note: without a server you will access URLs using file://somepath/index.html and anything other than this URL will result in 404 and no SPA framework can handle that.
I think the solution is to use a static site generator such as Jekyll or Middleman and allows you to convert information into static pages. That way you functionally are building a bunch of pages but they are all compiled ahead of time. You can add dynamic content that is loaded in from a yaml file and it will compile the content into separate html pages.
It is not possible, but there is a workaround using url parameters like this:
my-folder/index.html
my-folder/index.html?=about
my-folder/index.html?=about/sublevel
my-folder/index.html?=profile
my-folder/index.html?=./games
const urlParams = new URLSearchParams(location.search);
const route = urlParams.get('');
console.log(route);
// Should print "about" "about/sublevel" "profile" "./games"
Of course this approach is not as clean as using a server for routing, but it's the best you can get without a server.
BTW. I tried an alternative solution creating symlinks with all the target routes pointing to the same index.htmlfile. But it did not work because the browser (firefox) redirects by default when it finds a symlink, thus home is shown all the time.
How can I deeplink to my Ember app from outside ?
Say I want to deeplink to within my ember route (mainPage\deepRoute)
So when user clicks on the external link (not part of my Ember app), he is directly taken to mainPage\deepRoute
How will I code such a link ?
I assume by default the Ember application template would be rendered, but I want to direct route to some other link/template ?
You can simply link inside to any route of your Ember.js app directly, however your webserver has to be configured with url redirect to the index.html.
For example, if you use nginx as a webserver, you should have something like this in your nginx config file:
location / {
try_files $uri /index.html;
}
Option Two: if you cannot update the webserver, for example, you use GitHub pages, you have to use the #-ed url option. In this case, a url looks like this: example.com/#/posts/1/comments
More info here: http://guides.emberjs.com/v2.1.0/configuring-ember/specifying-url-type/
Make sure the server will load the single Ember html page for that url. You can create a 'catchall' route in your web framework that aliases (not redirects to) your index.html view, - probably at the bottom of your server route definitions - or manually alias whichever specific route you are concerned with.
Then once Ember is loaded it will enter the route specified in the url and use any query params that were specified.
I just removed # tag from my url of angular single page app.
I did like.
$locationProvider.html5Mode(true);
And It worked fine.
My problem is when I directly enter any url to the browser it showing a 404 error. And its working fine when I traverse throughout the app through links.
Eg: www.example.com/search
www.example.com/search_result
www.example.com/project_detail?pid=19
All these url's are working fine. But when I directly enter any of the above url's into my browser it showing a 404 error.
Please any thoughts on it.
Thanks in advance.
Well i had a similar problem. The server side implementation included Spring in my case.
Routing on client side ensures that all the url changes are resolved on the client side. However, When you directly enter any such url in the browser, the browser actually goes to the server for retrieving a web page corresponding to the url.
Now in your case, since these are VIRTUAL urls, that are meaningful on the client side, the server throws 404.
You can capture page not found exception at your server side
implementation, and redirect to the default page [route] in your app.
In Spring, we do have handlers for page not found exceptions, so i
guess they'll be available for your server side implementation too.
When using the History API you are saying:
"Here is a new URL. The other JavaScript I have just run has transformed the page into the page you would have got by visiting that URL."
This requires that you write server side code that will build the page in that state for the other URLs. This isn't a trivial thing to do and will usually require a significant amount of work.
However, in exchange for that work you get robustness and performance. When one of those URLs is visited it will:
work even if the JS fails for any reason (such as a dropped network connection or a client (such as a search engine) that doesn't support JS)
load faster than loading the homepage and then transforming it with JS
You need to use rewrite rules. Angular is an single page app, so all your request should go to the same file(index.html). You could do this by creating an .htaccess.
Assuming your main page is index.html.
Something like this (not tested):
RewriteRule ^(.)*$ / [L,QSA]
L flag means that if the rule matches, don't execute the next RewriteRule.
QSA means that the URL query parameters are also passed with the rewrited url.
More info about htaccess: http://httpd.apache.org/docs/2.2/howto/htaccess.html
google map does this thing where if I browse to, say, Australia, the URL changes to
https://www.google.com/maps/#-28.0345854,135.1500838,4z
I'm interested in doing something like this on my web application. So far I have this:
var baseurl = window.location.href.split("/#")[0]
window.history.replaceState( {} , 'foo', baseurl+'/#foo' );
which works just fine for adding "/#foo" to the url
My problem is that, after adding /#foo, the URL doesn't work, it 404es.
I'm not interested in modifying the brower's history, that's why I use replaceState instead of pushState.
anyway, is there a way to do this with js? or do I need server-side code to serve the appropriate page?
thankyou
You "need server-side code to serve the appropriate page". an # character is still part of the URL and therefore needs to be handled by the server. If you want to handle the this kind of situation client side only then what you want is to use # instead. anything after a hash is handle client side and does not trigger a new page to load from the server.
Several libraries use this to replicate routing in a single page HTML only app. For example:
Backbone.js Router
jQuery-Router
jquerymobile-router
Ember.Router
And many more.
While developing my app (asp.net mvc3) locally everything was fine using the VS dev app server. The app was located at localhost/. However, I'm attempting to deploy the application on a IIS 7.5 server in a /Management directory and having a lot of routing issues as a few calls in my app rely on the app being at the route.
I have some javascript code that calls my controller through an ajax call that looks like this:
url: "/en/Home/GetFormula/"
I would like it to go to: /Management/en/Home/GetFormula but instead it's going to the root of the site and looking for /en/Home/GetFormula and returning 404 errors.
Any ideas on how I can fix my javascript routing to default /Management/ as the root of the site?
Thanks
When the pseudo-URL passed to an HTTP request begins with a slash (e.g. "/path/to/resource"), the pseudo-URL is "completed" by treating it as if the given path were under the Web site's root directory (e.g. "http://my.site/path/to/directory").
Clearly, you were expecting the pseudo-URL to be processed as if the given path were under your Web application's root directory. Well, I have bad news for you: The HTTP protocol does not deal with such a thing as a "Web application".
The ASP.NET MVC Framework provides the Url.Content function, which takes pseudo-URLs beginning with a tilde character (e.g., "~/path/to/resource") and returns the result of replacing the tilde character with the Web application's root directory (e.g., "http://my.site/an/application/path/to/resource", assuming the Web application's root directory is "http:/my.site/an/application"). However, the ASP.NET MVC Framework is only available on the server side. If your JavaScript runs on the client side, it cannot call Url.Content.
But not all is lost. The ASP.NET MVC Framework allows you to dynamically generate JavaScript code on the server and run it on the client, the same way it allows you to dynamically generate HTML content and of course send it to the client. That way, you can expand the pseudo-URLs into actual URLs on the server side, and deploy the resulting JavaScript code to the client.
To avoid confusion about where you are currently try:
url: document.URL + "/Management/Home/GetFormula"
I solved this issue adding a html hidden field on my page where, on the server side, I put the correct url inferred with the Url.RouteUrl method like this:
<input id="MyHiddenFieldName" name="MyHiddenFieldName" type="hidden" value="#Url.RouteUrl(new { area = "MyArea", controller = "MyController", action = "MyAction" />
then, on your javascript code you could do this:
url: $("#MyHiddenFieldName).val()