Загрузить изображения с TinyMCE и RoR на защищенную страницу

Мне не нужно конкретное решение, но кто-то, кто даст мне более точную подсказку, чтобы решить мою проблему. У меня есть интранет-приложение ruby ​​on rails 4, защищенное для входа в систему. В этом приложении у меня есть страница редактирования, где я также использую TinyMCE. У него есть возможность указать URL-адрес, по которому следует отправить изображение для его загрузки (см. здесь). Я реализовал процедуру загрузки с помощью CarrierWave, и она отлично работает вне TinyMCE. Если это возможно, я бы также сохранил этот плагин. Но, как я уже сказал, CarrierWave в настоящее время не работает с TinyMCE и асинхронной загрузкой.

Итак, у вас есть идея, как я могу загрузить изображение, но с правильным токеном сеанса (асинхронно). И URL картинки, которая не сохраняется в БД, а в тексте показывается в TinyMCE. Есть ли плагин, который может мне помочь, или что-то еще? Если вам нужна более подробная информация, пожалуйста, сообщите мне.

С уважением Марко


person Mainz007    schedule 06.02.2017    source источник


Ответы (1)


Вы должны использовать плагин изображения для TinyMCE и установить file_picker свойства и обратные вызовы, поэтому вы можете прикреплять файлы со стороны клиента, а не URL.

tinymce.init({
    // Include image plugin on plugin list
    plugins: [ 'image'],
    // Include image button on toolbar
    toolbar: ['image'],
    // Enable title field in the Image dialog
    image_title: true, 
    // Enable automatic uploads of images represented by blob or data URIs
    automatic_uploads: true,
    // URL of your upload handler
    // (YOU SHOULD MAKE AN ENDPOINT TO RECEIVE THIS AND RETURN A JSON CONTAINING: {location: remote_image_url})
    images_upload_url: '/text_images',
    // Here we add custom filepicker only to Image dialog
    file_picker_types: 'image', 
    // And here's your custom image picker
    file_picker_callback: function(cb, value, meta) {
      var input = document.createElement('input');
      input.setAttribute('type', 'file');
      input.setAttribute('accept', 'image/*');

      input.onchange = function() {
        var file = this.files[0];

        // Note: Now we need to register the blob in TinyMCEs image blob
        // registry.
        var id = 'blobid' + (new Date()).getTime();
        var blobCache = tinymce.activeEditor.editorUpload.blobCache;
        var blobInfo = blobCache.create(id, file);
        blobCache.add(blobInfo);

        // Call the callback and populate the Title field with the file name
        cb(blobInfo.blobUri(), { title: file.name });
      };

      input.click();
    }
});

Добавьте text_images в свой route.rb файл:

  match "text_images" => "text_images#create", via: :post

И создайте свое действие обработки следующим образом:

  def create
    if params[:file].class == ActionDispatch::Http::UploadedFile
        @image = Picture.new(image: params[:file])
        respond_to do |format|
          if @image.save
            format.json { render json: { "location": @image.image.url }.to_json, status: :ok }
          else
            format.json { render json: @image.errors, status: :unprocessable_entity }
          end
        end
      end
    end

Это очень грубая реализация, вы должны сделать ее более безопасной для вашего контекста приложения, проверяя и фильтруя большие или недопустимые файлы!

ОБНОВЛЕНИЕ: недавно было обновлено синтаксис новых версий TinyMCE для функции onchange, чтобы включить атрибут чтения результатов в метод создания объекта blobCache:

      input.onchange = function() {
      var file = this.files[0];

      var reader = new FileReader();
      reader.readAsDataURL(file);
      reader.onload = function () {
        // Note: Now we need to register the blob in TinyMCEs image blob
        // registry. In the next release this part hopefully won't be
        // necessary, as we are looking to handle it internally.
        var id = 'blobid' + (new Date()).getTime();
        var blobCache =  tinymce.activeEditor.editorUpload.blobCache;
        var blobInfo = blobCache.create(id, file, reader.result);
        blobCache.add(blobInfo);

        // call the callback and populate the Title field with the file name
        cb(blobInfo.blobUri(), { title: file.name });
      };
    };
person ErvalhouS    schedule 07.02.2017
comment
Пока спасибо за такой подробный ответ. Я попробую и отмечу ваш ответ как правильный, когда он сработает :) - person Mainz007; 08.02.2017
comment
Хорошо, ваш ответ продвинул меня дальше, но не решил проблему, что у меня было предупреждение CSRF при загрузке изображения. Мне пришлось написать свою собственную функцию images_upload_handler. Таким образом, я мог бы добавить csrf_token, который генерирует RoR. Теперь приложение больше не выдает предупреждение и убивает сеанс. Я напишу свое окончательное решение на выходных. - person Mainz007; 10.02.2017
comment
Вы должны облегчить себе жизнь, никогда больше не сталкиваться с этими проблемами stackoverflow.com/a/24196317/3399504 - person ErvalhouS; 10.02.2017
comment
Большое спасибо за эту идею! Теперь у меня есть тонкое и простое рабочее решение. - person Mainz007; 11.02.2017
comment
Это работает, но если вы используете скрепку для Picture, вам нужно будет игнорировать проверку типа файла, а также skip_before_action :verify_authenticity_token на конечной точке API для загрузки. - person Qwertie; 12.12.2017