Использование JQuery и Rails для создания предварительного просмотра ссылки

что меня интересует, так это реализация базовой версии инструмента предварительного просмотра ссылок в JQuery и RoR (аналогично тому, что есть у Facebook). Пользователь вводит URL-адрес в поле ввода. Функция jquery отслеживает, что вводится (используя keyup), и когда вводится действительный URL-адрес (без отправки пользователем чего-либо), функция jquery вызывает функцию rails, которая использует гем Nokogiri для поиска и возврата содержимого предварительного просмотра (например, заголовок , любые изображения и т. д.). Затем это содержимое возвращается функции jquery и отображается под полем ввода.

Что мне непонятно во всем этом, так это то, как данные передаются из функции jquery в рельсы и обратно.

Чтобы конкретизировать ситуацию, предположим, что я просто хочу получить заголовок введенного URL-адреса.

В моей функции JQuery я использую keyup для отслеживания таких вещей, как пробелы, возвраты и т. Д. На данный момент я не проверяю введенный URL-адрес (я могу сделать это позже)

var text; 

$("#text").keyup(function(e) {

    if(e.which == 13 || e.which == 32 || e.which == 17 || ) {

        text = $("text").val();
        $.get('/linkPreview', {text: text}, function(answer) {

            $("previewTitle").html(answer);
        }           
            )
    }

Вот тут я не уверен, как поступить. Я использую метод .get Jquery (правильно ли это?) для вызова функции rails и передачи текста в качестве введенного URL-адреса.

Затем я сопоставляю '/linkPreview' с действием linkPreview в моем контроллере страниц, в моем файле маршрутов:

match '/linkPreview', :to => 'pages#linkPreview'

Я также не уверен в чтении и передаче данных JSON в функции rails. Я пытаюсь использовать функции response_to и response_with, но не уверен, что это правильно (я использую гем Nokogiri для извлечения заголовка из html-адреса):

def linkPreview
    respond_to :json
@url = params[:text]
doc = Nokogiri::HTML(open(@url))
@title = doc.css(title)
respond_with(@title)
end

Поскольку я новичок в RoR и JQuery, я был бы очень признателен за любую помощь в отношении правильного способа вызова функции rails из JQuery, передачи данных JSON от одного к другому и любых других ресурсов, которые я рассматриваю по этим темам! Мне также было интересно, есть ли какой-либо рекомендуемый способ отладки ошибочного сценария (мой код явно не работает, но я не уверен, с чего начать поиск ошибок).

Благодаря тонну!


person amillet89    schedule 07.08.2012    source источник


Ответы (3)


Я знаю, что это старый вопрос, однако мне удалось заставить работать следующий код:

контроллер.rb

def linkpreview
    url = params[:url]
    preview = LinkPreviewParser.parse(url) # returns a Hash
    respond_to do |format|
        format.json { render :json => preview }
    end
end

приложение/модели/link_preview_parser.rb

class LinkPreviewParser
  def self.parse(url)
    doc = Nokogiri::HTML(open(url))
    page_info = {}
    page_info[:title] = doc.css('title').text
    return page_info
  end
end

маршруты.rb

match '/linkpreview', to: 'items#linkpreview'

ссылкаpreview.js

$(document).ready(function() {
  $("#url-submit").on('click', function() {
    var link = $("#url");
    setTimeout(function() {
      var text = $(link).val();
      // send url to service for parsing
      $.ajax('/linkpreview', {
        type: 'POST',
        dataType:'json',
        data: { url: text },
        success: function(data, textStatus, jqXHR) {
          $("#item_title").val(data['title']);
        },
        error: function() { alert("error"); }
      }); 
    }, 100);
  });
});
person Daniel Friis    schedule 28.05.2013

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

def link_preview
  url = params[:url]
  preview = LinkPreviewParser.parse(url) # returns a Hash
  respond_with(preview) #respond_with converts a hash to JSON
end

Затем, для более аккуратной организации и тестирования кода, вынесите код парсинга в отдельный класс.

приложение/модели/link_preview_parser.rb

class LinkPreviewParser
  def self.parse(url)
    doc = Nokogiri::HTML(open(@url))
    page_info = {}
    page_info[:title] = doc.css(title) # assuming this is right - I didn't check
    # ... more parsing logic if needed ...
    return page_info
  end
end

Это вернет объект json, который выглядит так: {'title': 'Some Webpage'}, который должен быть довольно легко обрабатывать в вашем javascript. И вы можете добавить другой атрибут по мере необходимости.

Я не проверял это, но я считаю, что это должно работать. Это самый простой подход, но если вы ожидаете много трафика, у этого есть серьезный недостаток. Поскольку запрос от браузера должен был бы ожидать другого запроса от сервера к внешнему веб-сайту, у вас будет много запросов, просто ожидающих бездействия. Так что в идеале вы хотели бы сделать это асинхронно. Это немного больше работы, поэтому выбирайте то, что лучше всего подходит для вас в данный момент.

person Adam Albrecht    schedule 07.08.2012
comment
Спасибо за помощь. Я выполнил ваш совет, но у меня все еще есть проблемы с получением ответа. Я думаю, что проблема в функции .get. Когда я запускаю действие linkPreview через отправку формы (а не через прослушиватель событий keyup), об ошибках не сообщается. Код Jquery: $.get('/linkPreview', {text: text}, function(preview) { $("#previewTitle").html("<div>"+preview.title+"</div>"); }); Это правильно? Я не уверен, как отлаживать, учитывая, что я не получаю ответа на своей странице. Еще раз спасибо заранее - person amillet89; 13.08.2012

Возможно, вы захотите проверить гем link_preview, который мы разработали в Socialcast: https://github.com/socialcast/link_preview. он обрабатывает большую часть внутренней обработки для вас

person Michael Andrews    schedule 21.04.2014