I am building Backbone abd Expressjs application.
When the page loads, I want to view my home page, which will be loaded with ajax from a local, public folder. Problem is that the browser is sending request to server and I got response Cannot GET /
And on server side, in app.js file there is no route for /
I made that route in a Backbone router.js file.
routes: {
"":"home
}
In short, I want index.html to be loaded from client, not from server.
Solution is to place index.html file inside of public folder.
Now, it can be loaded and manipulated locally with ajax ( like a template ). Also hash in the url will work ( no request to server ) - that was my main issue.
Related
I have hosted a static NextJS website on amazon S3. The website works fine when the homepage is loaded and then other pages are loaded by nav. But if a particular page(except homepage) is reloaded, the site returns 404.
Also, I have tried putting the error page route back to 'index.html' as suggested on some threads but didn't solve the issue. Instead, after every page refresh, the index page opens.
How do I resolve that when a person is on Page1.html(for example) and he his refresh, Page1.html loads not the homepage.
The right way to go is to add an error fallback to index.html in the S3 bucket's static web hosting configuration.
The reason of this is when a URL is hit (either by manual input in the browser or a refresh), it sends a request to /list to the S3's root server (the one managed by AWS) before it hits our bucket. That S3 server have no idea if this is a reactjs app or not, so it goes into the bucket to look for the /list in the root of my bucket, which doesn't exist, so it returns the 404 error.
However by adding the error fallback, now when it gets 404, it redirects the request to index.html, where the react app is defined and loaded into. In this case, the /list will go through the normal flow to reach the right router that handles page rendering, problem solved.
This is an MVC 6/WebApi application. I'm attempting to use WebApi on the backend with AngularJS on the frontend.
I have two static files: index.html and login.html
(There will eventually be more static files.)
My Angular app is contained in the index.html while views (such as /login) are loaded from static files (i.e. login.html).
If I go to my root URL, index.html is loaded just fine. However, if I go to /login, I receive a 404 page not found.
Now, let it be said, I DO NOT want to bog down my application with a bunch of controllers and views as it's unnecessary to simply serve static files. That's overkill.
I have my routes setup to serve API calls (i.e. ~/api/whatever). How I get MVC 6 to ignore all other routes?
FYI, it also appears that MapPageRoute is deprecated in MVC 6?
EDIT:
One thing I've done to actually get it working is add my own middleware to intercept the request. The code below is added after all of my default middleware in the Configure method:
app.Use(next => async context =>
{
if (context.Request.Path.Value.StartsWith("/api"))
await next.Invoke(context);
else
await context.Response.WriteAsync(System.IO.File.ReadAllText("index.html"));
});
This seems a bit much and it's just a hack. All it does is allows any request that begins with "/api" to go through (which is then picked up by the MVC middleware), but any other call is served with the contents of the index.html. So, if my requested URL is "/login", the index.html file is served, then Angular looks at the route and loads the login.html file into view.
Any other suggestions?
Okay, so since something didn't exist in the MVC 6/ASP.NET 5 framework, I've created my own middleware that provides a lot more flexibility. It has been added to GitHub and is available through NuGet.
The project page is: https://github.com/a11smiles/AngularMiddleware
I was able do what you are asking here. Basically, I added a catch all route to my index action:
[Route("{*path}")]
meaning if no MVC action does not exist, call my Index action and angular routing will take from there
My current setup is as follows:
Starting the server and going to localhost takes me to home.ejs as stated here (in my front end routing):
However, when I go to localhost:3000/posts, the posts template is infact not being injected into my index file (where my ui-view is). Ive been following the mean stack guide from thinkster, but have been making a few changes (not using inline templates)
My question is, how do I setup my routing such that localhost:3000/posts will actually take me to the posts page?
You are dealing with two types of routing, client side and server side. Client side is located in your app.config function in your angular code. That function should be calling html files, which are located in your public directory. These files are not rendered server side via express and they wouldn't not be able to read the ejs format.
Typically with MEAN stack applications, you just render your index file when the user logs in, and from there the Angular router takes over with html files and you handle your routing from there. If you don't want Angular routing, you have to set up your index.js file to render pages as they are called with res.render('posts')
You can change your posts.ejs file into an html file, and just call it via Angular when the user navigates to localhost/#/posts (depending on your version and configuration of Angular).
Your Express server side routing will handle your API calls as you have defined in index.js. In order to call those APIs, you will make GET or POST requests via Angular's $http method, through a service or factory.
Hope that helps, if not, let me know and I can elaborate or provide examples.
To solve this, I used Eric Hartmanns solution. By changing posts.ejs to posts.html, and letting the angular router take over on client side, the page was being rendered. However, when typing in localhost:3000/posts in the address bar, the page wasnt being rendered and the server was being hit for some reason. To get around that I simply made a new get route in express and re-rendered index whenever that route was hit like so:
router.get('/', function(req, res) {
res.render('index');
});
How do you get a server-side redirect to go to a certain view in an angular app? I am guessing it has something to do with the redirect not triggering the part after the hash, but can this limitation be beat?
More info
I'm redirecting from an MVC controller to a page with an angular app. I'm using ui-router. The page containing the ui-view gets rendered, but processing stops there. If I refresh twice or go to the URL manually the page works as expected.
The MVC controller is called from a form which posts a file to the server and asynchronously populates a database and redirects when it's finished.
I don't see the problem, you can send a full url with hash and all on the location header and the browser will follow it, just check the response headers for this:
http://web-cf8f140d-22d3-4acd-b7a5-f9fa4e15e094.runnablecodesnippets.com/
What you can't do is getting the hash part directly from the request on the server side.
I'm developing a single page application using angularJs with a layout page that will be available for all my pages, but now I want some pages to be loaded without the layout page included in it, how can I do that. Any idea on this. Remember my pages are not #razor rendered with .cshtml except the layout and the index page all the other pages in my app are .html files.
Index.cshtml:
<div data-ng-view></div> - This is where all my pages will get loaded in to using the ngRoute
_Layout.cshtml:
<body>
<aside><nav>....</nav></aside>
<section><header>...</header>RenderBody()</section> - This is where my index page gets called
<aside>....</aside>
</body>
Now, I would like to get my page still loaded through the #index as my application is SPA, but _Layout.cshtml should be ignored.
Any *.cshtml pages are rendered server side and then served to the client.
*.html pages are statically served to the client.
Usually any static resources are put in the "Content" folder. In my own personal project this is where I put my static html pages.
In other words, you are in fact using Razor. In this case, using a different _layout.cshtml is answered in this stackoverflow question:
How do I specify different Layouts in the ASP.NET MVC 3 razor ViewStart file?
Also, usually, in general, for an SPA app, data is served asynchronously through a REST API or a REST/JSON API. In which case, once you're layout is loaded client side, you shouldn't have to deal with *.cshtml files, you should only have to deal with pure data and your javascript on the client side takes care of rendering that data into html.
In my personal project, I have a HomeController that serves a static html page:
public class HomeController : Controller
{
public ActionResult Index()
{
return Redirect(Url.Content("~/Content/index.html"));
}
}
What happens here is that when the user goes to http://localhost/ it executes the Index action from the HomeController which redirects to a static html file that contains my layout.
Any requests after that are loaded using Ajax requests that return JSON data. In other words, for any following requests, I don't have to deal with Razor "*.cshtml" files.
You shouldn't need to "ignore" _layout.cshtml since you're suppose to be serving just data.