senny / pdfjs_viewer-rails

PDF.js viewer packaged as a Rails engine.
MIT License
114 stars 175 forks source link

When using relative root, pdfjs javascript assets do not load correctly #74

Open Alfeezy opened 3 years ago

Alfeezy commented 3 years ago

I'm sure there's something I'm overlooking here, but I haven't found a solution yet so I'll stick this here.

I have an application which uses a relative url for the production environment: Rails.application.config.action_controller.relative_url_root = "/myrelativeroot"

When loading a pdf in development, everything works as intended. However, when I try to do the same in production, I get the following error from the js console:

Loading Worker from “https://mywebsite/pdfjs/web/pdf.worker.js?version=1.10.100” was blocked because of a disallowed MIME type (“text/html”)

It turns out, this file doesn't exists. However, when I go to https://mywebsite/myrelativeroot/pdfjs/web/pdf.worker.js?version=1.10.100, the file can be found just fine. Somehow, I need to tell pdfjs to append the relative url in the right spot to find pdf.worker.js.

# routes.rb
mount PdfjsViewer::Rails::Engine => "pdfjs", as: 'pdfjs'
nik-ko commented 1 year ago

I was facing the same problem. I found no other solution than editing several files (see my fork https://github.com/nik-ko/pdfjs_viewer-rails.git). Here is what I've done:

subdir="<%= ENV['RAILS_RELATIVE_URL_ROOT'] %>"

cd ~
git clone https://github.com/senny/pdfjs_viewer-rails.git
cd pdfjs_viewer-rails
sed -i "s+'/pdfjs/web/+'${subdir}/pdfjs/web/+g" ./app/assets/javascripts/pdfjs_viewer/viewer.js
sed -i "s+url('/pdfjs/+url('${subdir}/pdfjs/+g" ./app/assets/stylesheets/pdfjs_viewer/pdfjs/viewer.css
sed -i "s+url(/pdfjs/+url(${subdir}/pdfjs/+g" ./app/assets/stylesheets/pdfjs_viewer/pdfjs/viewer.css
sed -i "s+url(\"/pdfjs/+url(\"${subdir}/pdfjs/+g" ./app/assets/stylesheets/pdfjs_viewer/pdfjs/viewer.css
sed -i "s+href=\"/pdfjs/+href=\"${subdir}/pdfjs/+g" ./app/views/pdfjs_viewer/viewer/_head.html.erb

mv ./app/assets/stylesheets/pdfjs_viewer/pdfjs/viewer.css ./app/assets/stylesheets/pdfjs_viewer/pdfjs/viewer.css.erb
mv ./app/assets/javascripts/pdfjs_viewer/viewer.js ./app/assets/javascripts/pdfjs_viewer/viewer.js.erb

gem uninstall pdfjs_viewer-rails
gem build pdfjs_viewer-rails.gemspec
gem install pdfjs_viewer-rails-0.3.2.gem

In the Gemfile put gem "pdfjs_viewer-rails", path: "~/pdfjs_viewer-rails"

Instead of these steps you can also use my fork in the Gemfile: gem 'pdfjs_viewer-rails', :git => 'https://github.com/nik-ko/pdfjs_viewer-rails.git'

To apply the changes in your application run:

bundle exec rake assets:precompile  
bundle install
rails restart   

In my application this required setting config.assets.js_compressor = Uglifier.new(harmony: true) in config/environments/production.rb

Finally, you have to change the config/application.rb in your application and set ENV['RAILS_RELATIVE_URL_ROOT'] = '/my-subdirectory' # preceding slash required!

mckaygerhard commented 1 year ago

i confirmed this is a bug that happened in several gems and rails itselft, happened also in stimulus reflex that due rails is a Domain oriented framework unfortunately, and developers assumed hijacked root

Also the documentation from rails are vage and lack of deeps ways to setup a non domain oriented application and as described in https://www.phaedrasolutions.com/blog/how-to-config-subdirectory-with-rails-nginx-unicorn and also well explained at https://jlintusaari.net/deploying-rails-application-to-subdirectory/

By example

In config/application.rb

module App
 class Application < Rails::Application
   ....
   config.action_cable.disable_request_forgery_protection = true
   config.relative_url_root = "/applicants"
   config.action_cable.url = "ws://localhost:3000/applicants/cable"
   ...
 end
end

In config.ru file:

map Rails::Application.config.relative_url_root || "/" do
 run Rails.Application
end

This seems do not work and action cable just request always to ws://localhost:3000/cable assets are requested still from root but works for some gems cos we put in config.ru this: Rails::Application.config.relative_url_root || "/" that means assets from root also will found.. but does not work for pdfjs as i tested (unless i am so newbie)

i found several details for this framework.