Backbone.js + Rails + IE routing - ruby-on-rails-3

In my rails app, I have two layouts/controllers for different actions.
Eseentially, I match the root / to gateway#index, along with a few other pages such as /login and /register
The actual app once logged has its own sets of URLs, such as /dashboard /dashboard/action /explore etc.
Because of the pushstate with IE, the url changes to /#dashboard and loads the layout/JS for the gateway pages.
My rails controller for root has the following code, which is resulting in an endless loop in all versions of IE
if #current_user
redirect_to '/dashboard/lists'
end
The following is the Backbone history initializer (coffeescript):
Backbone.history.start
pushState: true
root: '/dashboard/'
Even with this setting, the application renders the gateway layout/JS not the application, and keeps the faulty URL the same (not setting the root to /dashboard).
How can I have IE load the application layout/JS/CSS while still having a different layout for the root?

I was setting the root to an invalid route. I ended up doing the following:
Backbone.history.start
pushState: true
root: '/app/'
And creating a route to a controller that used the application template.

From the Backbone website:
For RESTful persistence, history support via Backbone.Router and DOM manipulation with Backbone.View, include json2.js, and either jQuery.
So have you included json2.js?

Related

Can't render iframe on another domain using rack-cors

I'm trying to render an iframe of App A within App B.
App A is a local Rails 5.0 app and is using https.
App B is hosted on Heroku and is using https.
I've tried implementing the rack-cors gem but with no success, and I've tried all the suggestions I can find on StackOverflow.
My cors.rb file, within App A:
Rails.application.config.middleware.insert_before 0, Rack::Cors do
allow do
origins 'https://app-b.herokuapp.com'
resource '/url/on/app_a/*',
headers: :any,
methods: :any
end
end
My config.ru file (I've tried with and without this):
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run Rails.application
require 'rack/cors'
use Rack::Cors do
allow do
origins 'https://app-b.herokuapp.com'
resource '/url/on/app_a/*',
headers: :any,
methods: :any
end
end
The error I get is: Refused to display 'https://app-a.com/' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
I am not sure if this is specifically to rack-cors, but I do know that the header 'X-Frame-Options' is intentionally set to 'sameorigin' for at least Rails 5. Most likely to prevent developers from unintentionally allowing someone to wrap their server in an iframe.
According to the docs, we can see that if the server sets this response as not 'sameorigin', then the browser will allow the HTML code to run. So what we need is to remove that header away. Chris Peters does a great job at this post. To save a click
class SomeController < ApplicationController
after_action :allow_iframe
private
def allow_iframe
response.headers.except! 'X-Frame-Options'
end
end
To apply this to all endpoints simply place the after_action line and the function code in the application controller, but I would suggest limiting this to only specific pages/controllers.

Single Page Application Routing

Modern single page applications use routing mechanisms which don't have to rely on fragments or additional url parameters, but simply leverage the url path. How does the browser know when to ask the server for a resource and when to ask the single page application for a spa-page controlled by a router? Is there a browser API which makes it possible to take over the control of url handing which is then taken over by e.g. the vue-router or another routing spa library?
In Vue Router (and I assume other libraries/frameworks are the same) this is achieved through the HTML5 history API (pushState(), replaceState(), and popstate) which allows you to manipulate the browser's history but won't cause the browser to reload the page or look for a resource, keeping the UI in sync with the URL.
For example, observe what happens to the address bar when you enter this command in your browser's console
history.pushState({urlPath:'/some/page/on/stackoverflow'},"",'/some/page/on/stackoverflow')
The new URL is even added to your browser's history so if you navigate away from the page and come back to it you'll be directed to the new URL.
Of course all these URLs are non-existent on the server. So to avoid the problem of 404 errors when a user tries to directly access a non-existent resource you'd have to add a fallback route that redirects to your index.html page where your app lives.
Vue Router's HTML5 History Mode
React Router's <BrowserRouter>
How does the browser know when to ask the server for a resource and
when to ask the single page application for a spa-page controlled by a
router?
SPA Frameworks use routing libraries.
Suppose your javascript app is already loaded in the browser. When you navigate to a route that is defined in your routes array, the library prevents an http call to the server and handles it internally in your javascript code. Otherwise the call is forwarded to the server as a GET Http request.
here is an answer that discribes this behaviour with a clear scenario

Ember gives 404 after page refresh 404 apache on localhost

This probably has to do with not using rails or hosting in couchapp, but I'd like to solve this problem without involving another layer of code.
I'm writing an Ember app, and when I refresh the browser on any route except the index (home) route I get a 404. Getting to routes only works when it's done through Ember code, such as {{#linkTo}}s or transitionTos.
Apache version: Server version: Apache/2.2.22 (Ubuntu)
This sounds like an issue with one (or all) of your model hooks. Since everything after the # doesn't get sent back to the server, so any link-to or transition wouldn't make any difference,
server/cow is the same to the server as server/cow#/comments/3/posts.
Aka, you might have been passing models down to each nested resource lower using a link-to, but when it reloads that route, the param in the url is passed to the model hook to resolve the model.
As was pointed out below in the comments, if you aren't using the hash tag (aka using location:history or location:none) you need to use some form of url rewrite at the root of your ember application so your url. Be aware that if you choose one of those options you are limiting the functionality of your application to modern browsers (http://caniuse.com/history).

rails redirect_to different subdomain, controller, and params

If a user tries to go to a specific page on a mobile device (say: myapp.com/foo) I want to redirect them to a different page on the mobile site with parameters (in this case: m.myapp.com/bar?param1=foo).
I've figured out how to redirect to a different page with parameters (like myapp.com/bar?param1=foo), but I cannot figure out how to redirect to another subdomain without providing the whole string as in: redirect_to "m.myapp.com/bar?param1=foo"
Depending on the version of Rails you are using, you can accomplish this via:
redirect_to some_url(subdomain: 'some_subdomain', some_param: 'foo')
The URL helpers accept a subdomain argument--as of Rails 3, I think.

creating a launch page in rails app

I am planning to create an app in rails but first I want to make a launch page. Having never made a launch page I am curious as to how others are doing it?
Do you creae a small rails application with controller and model that just collects email addresses? and then deploy the rails app? I'd prefer this way but it seems like an overkill to deploy a rails app just for a launch page...?
Also, how do you modify the routes file so that if users type anything after the url then only page that shows up is the laungh page.
Meaning, if my launch page is at http://mycoollaunchpage.com then if users mess around and type http://mycoollaunchpage.com/lkjlkjljk then it should redirect back to http://mycoollaunchpage.com
Your idea sounds good. Just a page with an email signup form would work well.
To redirect back to your home page, make a route glob in your routes.rb file, and have an action in your controller that just redirects back to your root.
# in routes.rb
match "*whatever", :controller => 'pages', :action => 'redirect_to_root'
# in your pages_controller.rb file
def redirect_to_root
redirect_to "/"
end
There is an awesome rails plugin available for this very requirement of yours ;)
https://github.com/vinsol/Launching-Soon/