Rails 3 проблема send_data; разница между производством и развитием - PullRequest
3 голосов
/ 24 октября 2011

У меня странная ошибка в моем приложении Rails 3.Я использую этот код для отправки изображений, которые не являются общедоступными:

image = open(f, "rb") { |io| io.read }
send_data(image, :disposition => 'inline')

Я использую этот код для отображения изображений на страницах администратора и страницах пользователей.Если я использую среду разработки , этот код работает нормально, и изображения отображаются на обеих страницах.Но если я использую среду production , эти изображения отображаются только на страницах администратора, но не на пользовательских страницах.Я могу нажать на изображения, которые не отображаются, и выбрать «свойства».Под типом изображения я вижу:

application/xhtml+xml

Но другие общедоступные изображения имеют тип изображения JPG / PNG или что-то в этом роде.

Какая разница между средами может приводить к тому, что изображения не работают, и как я могу это исправить, чтобы изображения правильно отображались на всех страницах?

1 Ответ

0 голосов
/ 13 мая 2014

У меня был отчетливо похожий симптом.Я знаю, что это старая проблема, и она уже решена, но я подумал, что могу поделиться результатами моей ситуации, которая оказалась другой причиной.

Я создавал файл CSV и использовал send_file для отправки файла вбраузер.В разработке это работало отлично, в производстве браузер сообщал, что страница не найдена.

Вот действие с контроллера.

def export
  @campaign = LiveEmailCampaign.find params[:id]
  @campaign.recipients_csv do |csv_file|
    send_file csv_file,
      filename: @campaign.name,
      type: Mime::CSV 
  end 
end

И CSV построен из этого кода в модели.

def recipients_csv
  tempfile = Tempfile.new(self.name.downcase.dasherize)
  CSV.open tempfile, 'w' do |csv|
    recipients.each do |recipient|
      csv << [recipient]
    end
  end
  yield tempfile
end

После нескольких минут исследования я определил, что виновником был конфликт между директивой XSendFile в Apache на рабочем сервере и временным путем, используемым для записи данных CSV.В моем случае XSendFile был установлен только для корневого каталога приложения, а временный файл находился в / tmp на сервере.

Вместо того, чтобы вмешиваться в конфигурацию XSendFile на уровне сервера, я просто дал указание Tempfile использовать папку tmp вприложение Rails.

Итак, я изменил вызов Tempfile в методе модели на этот

tempfile = Tempfile.new(self.name.downcase.dasherize)

Теперь Rails и Apache снова стали друзьями.Мне просто нужно реорганизовать этот код, потому что он явно не отменяет связь с созданным временным файлом.Рекомендуется явно отсоединять временные файлы.

...