3

I've created a widget show view in my Rails 6 application that I would like to be accessible for third party websites by using an iFrame. For managing the CORS I'm using the rack-cors Gem. But I'm not able to get it to work. Here's my setup:

The model (#app/models/player_widget.rb):

class PlayerWidget < ApplicationRecord
  belongs_to :feed, optional: true
end

The controller (#app/controllers/embed/player_widgets_controller.rb):

class Embed::PlayerWidgetsController < ApplicationController
  layout false
  def show
    @widget = PlayerWidget.find params[:id]
    @feed = @widget.feed
  end
end

The view (#app/views/embed/player_widgets/show.html.erb):

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <%= csrf_meta_tags %>
    <%= csp_meta_tag %>

    <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
    <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
    <%= stylesheet_pack_tag 'application', 'data-turbolinks-track': 'reload' %>

    <!--     Fonts and icons     -->
    <link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700|Roboto+Slab:400,700|Material+Icons+Outlined|Material+Icons" />
    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/latest/css/font-awesome.min.css" />
  </head>
  <body>
    <div class="card card-product">
      <div class="card-header card-header-image" data-header-animation="true">
        <a href="#pablo">
          <%= image_tag url_for(@feed.image)%>
        </a>
      </div>
      <div class="card-body">
        <div class="card-actions text-center">
          <button type="button" class="btn btn-danger btn-link fix-broken-card">
            <i class="material-icons">build</i> Fix Header!
          </button>
          <audio id="testAudio<%= @feed.id %>" src="<%= url_for(@feed.audiofile) %>" type="audio/mpeg"></audio>
          <button id="playAudio<%= @feed.id %>" type="button" class="btn btn-default btn-link" rel="tooltip" data-placement="bottom" title="Play">
            <i id="playIcon<%= @feed.id %>" class="material-icons-outlined">play_circle_outlined</i>
          </button>
          <button id="nextAudio<%= @feed.id %>" type="button" class="btn btn-default btn-link" rel="tooltip" data-placement="bottom" title="Forward">
            <i class="material-icons-outlined">fast_forward</i>
          </button>
        </div>
        <h4 class="card-title">
          <a href="#pablo"><%= @feed.name %></a>
        </h4>
        <div class="card-description">
          <%= @feed.description %>
        </div>
      </div>
      <div class="card-footer">
        <div class="price">
          <h4><%= @feed.short_entries_count %> items</h4>
        </div>
        <div class="stats">
          <p class="card-category">Source: <%= @feed.client.name %></p>
        </div>
      </div>
    </div>
    <%= godfather_js_tag(@feed) %>

  </body>
</html>

The route (#config/routes.erb):

Rails.application.routes.draw do
  root 'home#index'
  scope "/:locale", locale: /en|nl/ do
    devise_for :users
    get '/:locale' => 'home#index'
    get 'publishers' => 'pages#publishers'
    get 'about' => 'pages#about'
    get 'contact' => 'pages#contact'
    get 'news' => 'pages#news'
    get 'mag_inspiration_day' => 'pages#mag_inspiration_day'
    namespace :embed do
       resources :player_widgets, only: :show, path: "" # -> domain.com/en/embed/1
    end
    namespace :admin do
      root 'dashboard#index'
      resources :audio_uploads
      resources :jingle_uploads
      resources :clients
      resources :feeds
      resources :users
    end
    # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  end
end

The cors setup (#config/application.rb):

module RssToSpeech
  ...
  class Application < Rails::Application
    config.middleware.insert_before 0, Rack::Cors do
      allow do
        origins '*'
        resource '/embed.js', headers: :any, methods: :get
        resource '/en/embed/1', headers: :any, methods: :get
      end
    end
    ...
  end
end

The embed.js script (#public/embed.js):

window.onload = function() {

   //Params
   var scriptPram = document.getElementById('load_widget');
   var id = scriptPram.getAttribute('data-page');

   //iFrame
   var iframe = document.createElement('iframe');
   iframe.style.display = "none";
   iframe.src = "embed/" + id;
   document.getElementById('xs-iframe').appendChild(iframe);
};

The script on the third party website (where example is substituted with my own domain):

<div id="xs-iframe"></div>
<script id="load_widget" src="https://www.example.com/embed.js" data-page="1"></script>

A desperate attempt to get it to work on the third party website wit a iframe (where example is substituted with my own domain):

<iframe src="htt://www.example.com/embed/1" width="" height=""></iframe>

I'm getting the following error in my iframe view www.example.com refused to connect., where example is substituted with my own domain. My log isn't showing any error and says that it rendered the show-view without any problem.

Does anyone know what I'm doing wrong here?

0 Answers0