การให้บริการไฟล์คงที่ด้วย Sinatra


139

ฉันมีเว็บไซต์หน้าเดียวที่ใช้ HTML, CSS และ JavaScript ฉันต้องการปรับใช้แอพนี้กับ Heroku แต่ไม่สามารถหาวิธีที่จะทำได้ ตอนนี้ฉันกำลังพยายามทำให้แอปทำงานกับ Sinatra

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

myapp.rbและต่อไปนี้เป็นเนื้อหาของ

require 'rubygems'
require 'sinatra'

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

1
ฉันได้เรียนรู้ว่าการเข้าถึงlocalhost: 2345 / index.html ใช้งานได้
TK

คุณสามารถใช้ WebBrick เพื่อให้บริการไฟล์คงที่ในไม่กี่บรรทัด จากนั้นเรียกrequire 'webrick'; server = WEBrick::HTTPServer.new Port: 1234; server.mount '/', WEBrick::HTTPServlet::FileHandler, 'www/'; trap("INT") { server.stop }; server.start; ruby myapp.rbลบพอร์ตสำหรับ Heroku ใส่ในของคุณweb: ruby myapp.rb Procfileความคิดเห็นไม่ใช่คำตอบเพราะไม่ใช่สำหรับ Sinatra แต่ฉันคิดว่ามันง่ายต่อการพึ่งพา
Chloe

คำตอบ:


131

โดยไม่ต้องกำหนดค่าใด ๆ publicเพิ่มเติมซินาตร้าจะทำหน้าที่ในสินทรัพย์ สำหรับเส้นทางที่ว่างเปล่าคุณจะต้องการแสดงเอกสารดัชนี

require 'rubygems'
require 'sinatra'

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

เราต์ควรคืนค่าStringซึ่งกลายเป็นเนื้อความการตอบกลับ HTTP เปิดแฟ้มอ่านไฟล์ปิดไฟล์และผลตอบแทนที่File.readString


52
send_file File.expand_path('index.html', settings.public)คุณค่อนข้างควรจะทำอย่างไร
Konstantin Haase

32
ตอนนี้ไม่ถูกต้อง คุณควรแทนที่settings.publicด้วยsettings.public_folderรับsend_file File.expand_path('index.html', settings.public_folder)
Alistair Holt

2
@zhirzh send_fileก็ไม่สิ่งที่พิเศษสำหรับคุณgithub.com/sinatra/sinatra/blob/master/lib/sinatra/base.rb#L351
Iain

1
File.readอ่านไฟล์ทั้งหมดในหน่วยความจำ สิ่งนี้สามารถตกลงหรือไม่ขึ้นอยู่กับขนาดของไฟล์และจำนวนการร้องขอพร้อมกัน
Wayne Conrad

@WayneConrad ตรงข้าม send_file ไม่เป็นไร? หรือมันทำหน้าที่เหมือนกัน?
Ben

169

คุณสามารถใช้ตัวsend_fileช่วยในการให้บริการไฟล์

require 'sinatra'

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

สิ่งนี้จะทำหน้าที่index.htmlจากไดเรกทอรีใดก็ตามที่ได้รับการกำหนดค่าว่ามีไฟล์สแตติกของแอปพลิเคชันของคุณ


19
ฉันคิดว่าแอป Sinatra ที่ใหม่กว่าใช้set :public_folderดังนั้นคุณจะใช้settings.public_folderแทนsettings.public
Andrew

4
ฉันอัปเดตคำตอบเพื่อใช้การตั้งค่า public_folder แอพที่เก่ากว่าอาจยังต้องใช้การตั้งค่าสาธารณะ
Chad DeShon

62

คุณสามารถโฮสต์พวกเขาจากโฟลเดอร์สาธารณะและพวกเขาไม่ต้องการเส้นทาง

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

ใน myapp.rb

set :public_folder, 'public'

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

ลิงก์ไปยังโฟลเดอร์ย่อยบางโฟลเดอร์ในที่สาธารณะ

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

ทุกอย่างใน. /public สามารถเข้าถึงได้จาก '/whething/bla.html

ตัวอย่าง:
./public/stylesheets/screen.css
จะสามารถเข้าถึงได้ผ่าน '/stylesheets/screen.css' ไม่ต้องใช้เส้นทาง


1
จะเกิดอะไรขึ้นถ้าสาธารณะมีโฟลเดอร์ซ้อนกันหลายแห่ง (ซึ่งคุณไม่ต้องการสร้างเส้นทาง) ที่มีไฟล์ index.html ที่คุณต้องการเป็นค่าเริ่มต้น
ดีเร็กก่อน

ฉันได้ขยายการแก้ปัญหา ฉันหวังว่ามันจะช่วยให้ชัดเจนทุกอย่างสามารถเข้าถึงได้ในที่สาธารณะไม่จำเป็นต้องใช้เส้นทางเพียงแค่ตัดส่วน "สาธารณะ" ของเส้นทาง
มอร์แกน

1
ใช้ rackup บน Heroku set :public_folder, 'public'ผมใช้ นั่นคือกุญแจสำคัญในการทำให้มันใช้งานได้แม้จะมีเอกสารของ Sinatra ซึ่งหมายความว่าสิ่งนี้ได้ถูกกำหนดเป็นค่าเริ่มต้นแล้ว
Daniel C

12

โปรดทราบว่าในการผลิตคุณสามารถให้เว็บเซิร์ฟเวอร์ของคุณส่งออกindex.htmlโดยอัตโนมัติเพื่อที่คำขอจะไม่ถูกส่งไปยัง Sinatra สิ่งนี้จะดีกว่าสำหรับการทำงานเนื่องจากคุณไม่ต้องผ่าน Sinatra / Rack stack เพียงเพื่อให้บริการข้อความคงที่ซึ่งเป็นสิ่งที่ Apache / Nginx ทำได้ยอดเยี่ยม


โอ้ใช่แล้ว ฉันจะใช้ Erb จากนั้นและใช้ Varnish เป็นเงินสด
ma11hew28

2
คุณจะกำหนดค่าสิ่งนี้ในการผลิตได้อย่างไร ฉันได้ค้นหาเอกสารเกี่ยวกับการอ้างอิงโยงนี้กับ Sinatra และ Rack แต่หาไม่พบ โดยทั่วไปฉันต้องการ index.html ที่จะโหลดในใด ๆ / โฟลเดอร์สาธารณะที่มีอย่างใดอย่างหนึ่งหากผู้ใช้เพียงแค่ใส่ชื่อโฟลเดอร์

12

ซินาตร้าควรอนุญาตให้คุณให้บริการไฟล์คงที่จากไดเรกทอรีสาธารณะตามที่อธิบายไว้ในเอกสาร :

ไฟล์คงที่

ไฟล์สแตติกให้บริการจากไดเรกทอรี. /public คุณสามารถระบุตำแหน่งอื่นได้โดยการตั้งค่า: ตัวเลือกสาธารณะ:

โปรดทราบว่าชื่อไดเรกทอรีสาธารณะไม่รวมอยู่ใน URL ไฟล์. /public/css/style.css มีให้ในรูปแบบ example.com/css/style.css


4
ทำไมถึงมีคะแนนโหวต 4 ไม่ตอบคำถามเกี่ยวกับวิธีการนำเสนอเอกสารเริ่มต้นเมื่อมีการร้องขอโฟลเดอร์
ดีเร็กก่อน


2

ซินาตร้า assetpackอัญมณีมีทั้งกลุ่มของคุณสมบัติ ไวยากรณ์หวาน

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

ในขณะที่ฉันยังคงมีปัญหาเกี่ยวกับท่อส่งทรัพย์สินทางรถไฟฉันรู้สึกว่าฉันควบคุมได้มากขึ้นเมื่อใช้sinatra-assetpack - แต่ส่วนใหญ่มันใช้งานได้กับโค้ดไม่กี่บรรทัดเท่านั้น


2

คำตอบที่อัปเดต : ฉันเชื่อมโยงทั้งหมดข้างต้นโดยไม่มีโชคในการโหลด css, js .... เนื้อหาอื่น ๆ สิ่งเดียวที่โหลดคือ index.html ... และส่วนที่เหลือกำลัง = >>404 error

โซลูชันของฉัน: โฟลเดอร์แอปมีลักษณะเช่นนี้

index.rb == >> รหัส Sinatra ไป

require 'rubygems'
require 'sinatra'

get '/' do
  html :index
end

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

public folder== >> มีทุกอย่างอื่น ... 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$

ตอนนี้เริ่มต้นเซิร์ฟเวอร์และคุณจะสามารถนำทางผ่านหน้าสแตติกได้โดยไม่มีปัญหา

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

คุณอาจพิจารณาย้ายindex.htmlไฟล์ไปที่views/index.erbและกำหนดจุดสิ้นสุดเช่น:

get '/' do
  erb :index
end


0

การวางไฟล์ในpublicโฟลเดอร์มีข้อ จำกัด ที่จริงแล้วเมื่อคุณอยู่ในรูท'/'พา ธ จะทำงานได้อย่างถูกต้องเพราะเบราว์เซอร์จะตั้งค่าพา ธ สัมพัทธ์ของไฟล์ css ของคุณตัวอย่างเช่นซินาต/css/style.cssร้าจะค้นหาไฟล์ในpublicไดเรกทอรี อย่างไรก็ตามหากตำแหน่งของคุณเป็นตัวอย่าง/user/createเว็บเบราว์เซอร์จะค้นหาไฟล์ css ของคุณ/user/create/css/style.cssและจะล้มเหลว

เพื่อเป็นการแก้ปัญหาฉันเพิ่มการเปลี่ยนเส้นทางต่อไปนี้เพื่อโหลดไฟล์ css อย่างถูกต้อง

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

-7

แล้วโซลูชันนี้ล่ะ? :

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

ดังนั้นหากคุณไปที่ (ตัวอย่าง) / ไดเรกทอรีย่อย / test / มันจะโหลดไดเรกทอรีย่อย / test / index.html

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.