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.