Statische Dateien mit Sinatra bereitstellen


139

Ich habe eine einseitige Website, die nur HTML, CSS und JavaScript verwendet. Ich möchte die App für Heroku bereitstellen, kann aber keinen Weg finden, dies zu tun. Ich versuche jetzt, die App mit Sinatra zum Laufen zu bringen.

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

Und das Folgende ist der Inhalt von myapp.rb.

require 'rubygems'
require 'sinatra'

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

1
Ich habe erfahren, dass der Zugriff auf localhost: 2345 / index.html funktioniert.
TK.

Mit WebBrick können Sie statische Dateien in wenigen Zeilen bereitstellen. require 'webrick'; server = WEBrick::HTTPServer.new Port: 1234; server.mount '/', WEBrick::HTTPServlet::FileHandler, 'www/'; trap("INT") { server.stop }; server.start;Dann renne ruby myapp.rb. Entfernen Sie den Anschluss für Heroku. Setzen Sie web: ruby myapp.rbIhre Procfile. Kommentar nicht antworten, da es nicht für Sinatra ist, aber ich denke, es vereinfacht Abhängigkeiten.
Chloe

Antworten:


131

Ohne zusätzliche Konfiguration wird Sinatra Assets in bereitstellen public. Für die leere Route möchten Sie das Indexdokument rendern.

require 'rubygems'
require 'sinatra'

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

Routen sollten a zurückgeben, Stringdas zum HTTP-Antworttext wird. File.readöffnet eine Datei, liest die Datei, schließt die Datei und gibt a zurück String.


52
Du solltest es lieber tun send_file File.expand_path('index.html', settings.public).
Konstantin Haase

32
Das ist jetzt falsch. Sie sollten ersetzen settings.publicmit settings.public_folderbekommensend_file File.expand_path('index.html', settings.public_folder)
Alistair Holen

2
@zhirzh send_file, es macht zusätzliche Dinge für Sie github.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L351
iain

1
File.readLiest die gesamte Datei in den Speicher. Dies kann in Ordnung sein oder nicht, abhängig von der Größe der Dateien und der Anzahl der gleichzeitigen Anforderungen.
Wayne Conrad

@ WayneConrad auf der anderen Seite, send_file ist okay? oder verhält es sich gleich?
Ben

169

Sie können den send_fileHelfer verwenden, um Dateien bereitzustellen.

require 'sinatra'

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

Dies dient index.htmlaus jedem Verzeichnis, in dem die statischen Dateien Ihrer Anwendung konfiguriert sind.


19
Ich denke, neuere Sinatra-Apps verwenden set :public_folder, also würden Sie settings.public_folderanstelle vonsettings.public
Andrew

4
Ich habe die Antwort aktualisiert, um settings.public_folder zu verwenden. Ältere Apps müssen möglicherweise noch settings.public verwenden.
Chad DeShon

62

Sie können sie einfach aus dem öffentlichen Ordner hosten und sie benötigen keine Routen.

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

In der myapp.rb

set :public_folder, 'public'

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

Link zu einem öffentlichen Unterordner

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

Alles in ./public ist über '/whatever/bla.html zugänglich

Beispiel:
./public/stylesheets/screen.css
Der Zugriff erfolgt über '/stylesheets/screen.css'. Keine Route erforderlich


1
Was ist, wenn public viele verschachtelte Ordner hat (für die Sie keine Routen erstellen möchten), die index.html-Dateien enthalten, die Sie als Standard verwenden möchten?
Derek Prior

Ich habe die Lösung erweitert. Ich hoffe, es hilft zu klären, alles ist öffentlich zugänglich, keine Route erforderlich, nur den "öffentlichen" Teil des Pfades weglassen.
Morgan

1
Mit Rackup auf Heroku musste ich verwenden set :public_folder, 'public'. Dies war der Schlüssel, damit es funktioniert, obwohl die Sinatra-Dokumentation impliziert, dass dies bereits als Standard festgelegt wurde.
Daniel C

12

Denken Sie daran, dass Sie in der Produktion Ihren Webserver index.htmlautomatisch senden lassen können, damit die Anfrage niemals an Sinatra geht. Dies ist besser für die Leistung, da Sie nicht den Sinatra / Rack-Stapel durchlaufen müssen, um statischen Text bereitzustellen, was Apache / Nginx hervorragend können.


Oh ja, duh. Ich werde dann einfach Erb verwenden und Lack verwenden, um es einzulösen.
ma11hew28

2
Wie konfigurieren Sie dies in der Produktion? Ich habe nach Dokumentation zu diesem Querverweis mit Sinatra und Rack gesucht, kann sie aber nicht finden. Grundsätzlich möchte ich, dass index.html in einen beliebigen / öffentlichen Ordner geladen wird, der einen hat, wenn der Benutzer nur den

12

Mit Sinatra sollten Sie statische Dateien aus dem öffentlichen Verzeichnis bereitstellen können, wie in den Dokumenten erläutert :

Statische Dateien

Statische Dateien werden aus dem Verzeichnis ./public bereitgestellt. Sie können einen anderen Speicherort angeben, indem Sie die Option: public festlegen:

Beachten Sie, dass der Name des öffentlichen Verzeichnisses nicht in der URL enthalten ist. Eine Datei ./public/css/style.css wird als example.com/css/style.css zur Verfügung gestellt.


4
Warum hat das 4 Stimmen? Die Frage, wie ein Standarddokument angezeigt werden soll, wenn ein Ordner angefordert wird, wird nicht beantwortet.
Derek Prior


2

Das Sinatra-Assetpack- Juwel bietet eine ganze Reihe von Funktionen. Syntax ist süß:

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

Während ich immer noch Probleme mit der Rails-Assets-Pipeline habe, habe ich das Gefühl, dass ich mit sinatra-assetpack viel mehr Kontrolle habe - aber meistens funktioniert es nur mit ein paar Codezeilen.


2

AKTUALISIERTE ANTWORT : Ich habe alle oben genannten Punkte gebunden, ohne das Glück zu haben, CSS-, JS- usw. Inhalte laden zu können. Das einzige, was geladen wurde, ist index.html ... und der Rest ging = >>404 error

Meine Lösung: Der App-Ordner sieht so aus.

index.rb == >> Sinatra Code geht.

require 'rubygems'
require 'sinatra'

get '/' do
  html :index
end

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

public folder== >> enthält alles andere ... css, js, bla bla ... 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$

Starten Sie nun den Server und Sie können problemlos durch statische Seiten navigieren.

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

Sie können die index.htmlDatei verschieben views/index.erbund einen Endpunkt wie folgt definieren:

get '/' do
  erb :index
end

0

Das Ablegen von Dateien in publicOrdnern unterliegt einer Einschränkung. Wenn Sie sich im Stammpfad '/'befinden, funktioniert dies tatsächlich korrekt, da der Browser beispielsweise den relativen Pfad Ihrer CSS-Datei /css/style.cssfestlegt und sinatra nach der Datei im publicVerzeichnis sucht . Wenn sich Ihr Standort jedoch beispielsweise befindet /user/create, sucht der Webbrowser nach Ihrer CSS-Datei /user/create/css/style.cssund schlägt fehl.

Um dieses Problem zu umgehen, habe ich die folgende Umleitung hinzugefügt, um die CSS-Datei korrekt zu laden:

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


-7

Was ist mit dieser Lösung? ::

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

Wenn Sie jetzt zu (zum Beispiel) / Unterverzeichnis / Test / navigieren, wird das Unterverzeichnis / Test / Index.html geladen

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.