Serve file statici con Sinatra


139

Ho un sito Web di una pagina che utilizza solo HTML, CSS e JavaScript. Voglio distribuire l'app su Heroku, ma non riesco a trovare un modo per farlo. Ora sto cercando di far funzionare l'app con Sinatra.

.
|-- application.css
|-- application.js
|-- index.html
|-- jquery.js
`-- myapp.rb

E il seguente è il contenuto di myapp.rb.

require 'rubygems'
require 'sinatra'

get "/" do
  # What should I write here to point to the `index.html`
end

1
Ho imparato che l'accesso a localhost: 2345 / index.html funziona.
TK.

Puoi usare WebBrick per servire file statici in poche righe. require 'webrick'; server = WEBrick::HTTPServer.new Port: 1234; server.mount '/', WEBrick::HTTPServlet::FileHandler, 'www/'; trap("INT") { server.stop }; server.start;Quindi corri ruby myapp.rb. Rimuovi la porta per Heroku. Inserisci il web: ruby myapp.rbtuo Procfile. Il commento non risponde in quanto non è per Sinatra, ma penso che semplifichi le dipendenze.
Chloe,

Risposte:


131

Senza alcuna configurazione aggiuntiva, Sinatra servirà le risorse in public. Per il percorso vuoto, ti consigliamo di eseguire il rendering del documento indice.

require 'rubygems'
require 'sinatra'

get '/' do
  File.read(File.join('public', 'index.html'))
end

Le route dovrebbero restituire una Stringche diventa il corpo della risposta HTTP. File.readapre un file, legge il file, chiude il file e restituisce a String.


52
Dovresti piuttosto farlo send_file File.expand_path('index.html', settings.public).
Konstantin Haase,

32
Questo ora non è corretto. Dovresti sostituirlo settings.publiccon settings.public_folderper otteneresend_file File.expand_path('index.html', settings.public_folder)
Alistair Holt

2
@zhirzh send_file, lo fa roba in più per voi github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L351
Iain

1
File.readlegge l'intero file in memoria. Questo può essere OK o meno, a seconda della dimensione dei file e del numero di richieste simultanee.
Wayne Conrad,

@WayneConrad al contrario, send_file va bene? o si comporta allo stesso modo?
Ben

169

Puoi usare l' send_filehelper per servire i file.

require 'sinatra'

get '/' do
  send_file File.join(settings.public_folder, 'index.html')
end

Questo servirà index.htmlda qualunque directory sia stata configurata come contenente i file statici dell'applicazione.


19
Penso che le app Sinatra più recenti utilizzino set :public_folder, quindi useresti settings.public_folderinvecesettings.public
Andrew

4
Ho aggiornato la risposta per utilizzare settings.public_folder. Le app meno recenti potrebbero aver ancora bisogno di usare settings.public.
Chad DeShon,

62

Potresti semplicemente ospitarli dalla cartella pubblica e non hanno bisogno di percorsi.

.
-- myapp.rb
`-- public
    |-- application.css
    |-- application.js
    |-- index.html
    `-- jquery.js

Nel myapp.rb

set :public_folder, 'public'

get "/" do
  redirect '/index.html'
end

Link ad alcune sottocartelle in pubblico

set :public_folder, 'public'
get "/" do
  redirect '/subfolder/index.html' 
end

Tutto in ./public è accessibile da '/whatever/bla.html

Esempio:
./public/stylesheets/screen.css
Sarà accessibile tramite '/stylesheets/screen.css' nessun percorso richiesto


1
cosa succede se il pubblico ha molte cartelle nidificate (per le quali non si desidera creare route) con file index.html che si desidera impostare come predefiniti?
Derek prima del

Ho ampliato la soluzione. Spero che aiuti a chiarire, tutto è accessibile in pubblico, nessun percorso richiesto è sufficiente omettere la parte "pubblica" del percorso.
Morgan,

1
usando il rackup su Heroku ho dovuto usare set :public_folder, 'public'. Questa era la chiave per farlo funzionare, nonostante la documentazione di Sinatra suggerisse che questo era già impostato come predefinito.
Daniel C,

12

Tieni presente che in produzione è possibile inviare index.htmlautomaticamente il tuo server Web in modo che la richiesta non arrivi mai a Sinatra. Questo è meglio per le prestazioni in quanto non è necessario passare attraverso lo stack Sinatra / Rack solo per servire testo statico, che è ciò che Apache / Nginx sono fantastici nel fare.


Oh sì, duh. Allora userò semplicemente Erb e userò Varnish per incassarlo.
ma11hew28,

2
Come si configura questo in produzione? Ho cercato documentazione su questo riferimento incrociato con Sinatra e Rack ma non riesco a trovarlo. Fondamentalmente voglio che index.html sia caricato in una cartella / public che ne abbia una se l'utente inserisce solo il nome della cartella

12

Sinatra dovrebbe lasciarti servire i file statici dalla directory pubblica come spiegato nei documenti :

File statici

I file statici vengono forniti dalla directory ./public. È possibile specificare una posizione diversa impostando l'opzione: public:

Si noti che il nome della directory pubblica non è incluso nell'URL. Un file ./public/css/style.css è reso disponibile come esempio.com/css/style.css.


4
Perché questo ha 4 voti? Non risponde alla domanda su come presentare un documento predefinito quando viene richiesta una cartella.
Derek prima del


2

la gemma sinatra-assetpack offre tutta una serie di funzionalità. la sintassi è dolce:

serve '/js', from: '/app/javascripts'

mentre sto ancora riscontrando problemi con la pipeline delle risorse di rotaie, mi sembra di avere un controllo molto maggiore usando sinatra-assetpack - ma il più delle volte funziona solo con poche righe di codice.


2

RISPOSTA AGGIORNATA : ho legato tutto quanto sopra senza fortuna di essere in grado di caricare i contenuti CSS, js .... ecc. L'unica cosa che stava caricando è index.html ... e il resto stava andando = >>404 error

La mia soluzione: la cartella dell'app si presenta così.

index.rb == >> Il codice Sinatra va.

require 'rubygems'
require 'sinatra'

get '/' do
  html :index
end

def html(view)
  File.read(File.join('public', "#{view.to_s}.html"))
end

public folder== >> contiene tutto il resto ... css, js, blah blah..etc.

user@user-SVE1411EGXB:~/sintra1$ ls
index.rb  public
user@user-SVE1411EGXB:~/sintra1$ find public/
public/
public/index.html
public/about_us.html
public/contact.html
public/fonts
public/fonts/fontawesome-webfont.svg
public/fonts/fontawesome-webfont.ttf
public/img
public/img/drink_ZIDO.jpg
public/js
public/js/bootstrap.min.js
public/js/jquery.min.js
public/js/bootstrap.js
public/carsoul2.html
public/css
public/css/font-awesome-ie7.css
public/css/bootstrap.min.css
public/css/font-awesome.min.css
public/css/bootstrap.css
public/css/font-awesome.css
public/css/style.css
user@user-SVE1411EGXB:~/sintra1$

Ora avvia il server e sarai in grado di navigare tra le pagine statiche senza problemi.

user@user-SVE1411EGXB:~/sintra1$ ruby index.rb 
== Sinatra/1.4.5 has taken the stage on 4567 for development with backup from Thin
>> Thin web server (v1.5.1 codename Straight Razor)
>> Maximum connections set to 1024
>> Listening on localhost:4567, CTRL+C to stop

2
require 'rubygems'
require 'sinatra'

set :public_folder, File.dirname(__FILE__) + '/../client'
#client - it's folder with all your file, including myapp.rb

get "/" do
  File.read('index.html')
end



1

Potresti considerare di spostare il index.htmlfile in views/index.erbe definire un endpoint come:

get '/' do
  erb :index
end

0

Mettere i file nella publiccartella ha un limite. In realtà, quando ci si trova nel '/'percorso principale funziona correttamente perché il browser imposterà il percorso relativo del file css, ad esempio, /css/style.csse sinatra cercherà il file nella publicdirectory. Tuttavia, se la tua posizione è ad esempio /user/create, il browser cercherà il tuo file CSS /user/create/css/style.csse fallirà.

Per ovviare al problema, ho aggiunto il seguente reindirizzamento per caricare correttamente il file CSS:

get %r{.*/css/style.css} do
    redirect('css/style.css')
end

-7

E questa soluzione? :

get "/subdirectory/:file" do 
  file = params[:file] + "index.html"
  if File.exists?(params[:file])
    return File.open("subdirectory/" + file)
  else
   return "error"
  end
end

quindi se ora vai a (ad esempio) / sottodirectory / test / caricherà la sottodirectory / test / index.html

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.