Ответ на запрос AJAX Rails с переменной экземпляра. js .erb и Rails - PullRequest
0 голосов
/ 02 мая 2020

Я борюсь с / 1048 * AJAX запросами в Rails. Здесь есть официальное руководство , но у меня возникают небольшие трудности с его сопоставлением с ES6 JS. У меня проблемы с передачей информации на мой интерфейс после выполнения моих запросов.

У меня есть JS вызов window.onload, потому что я пытаюсь найти размер экрана пользователя (среди прочего) и передать его обратно в Rails:

    let xhttp = new XMLHttpRequest();
    const url = "/users";
    xhttp.open("POST", url);
    // Some other things added to it...
    xhttp.onreadystatechange = function() {
        if (this.readyState == 4 && this.status == 201) {
            console.log(this.responseText);
       }
    };
    xhttp.send(JSON.stringify({user_info: userInfo}));

Это публикует / пользователи некоторую информацию о сеансе. Это проходит хорошо. Обратите внимание на console.log, который отслеживает ответ, мы вернемся к этому позже.

В моем контроллере Rails:

def create
  user_info = params[:user_info].permit!
  user_info = user_info.to_s
  @fingerprint_user =  User.find_or_create_by(fingerprint: user_info)
  respond_to do |format|
    # NOTE: I have tried a few things here
    # format.html { redirect_to @fingerprint_user, notice: "Successfully identified user by fingerprint." }
    # format.js
    format.json { render json: @fingerprint_user, status: :created, head: :ok }
  end
end

Отправитель JSON работает правильно . Console.log в JS выше корректно console.logs полученные JSON. На запрос отвечает 201 и переменная экземпляра @fingerprint_user в форме JSON.

Моя проблема с возвратом ERB JS с переменной экземпляра . Как показано в руководстве, я попытался добавить format.js. Затем запрос возвращает 200 и содержимое моего views/users/create.js.erb файла:

console.log("hello");

Однако на самом деле это не вход в консоль.

Наконец, я попытался использовать все поля формата (js, html и json). Вот мой show.html.erb:

<p>Got user: <%= @fingerprint_user.to_s %> </p>

Вот лучший views/users/create.js.erb файл, где fingerprint - это div в моем index.html.erb:

console.log("hello");
$("<%= escape_javascript(render @fingerprint_user) %>").appendTo("#fingerprint");

Еще раз, ответ: 200 и соответствующий html, но это не отображается на странице.

1 Ответ

1 голос
/ 02 мая 2020

Выполнение запросов для AJAX запросов для JavaScript отличается от запроса JSON. Вместо того, чтобы запрашивать некоторые данные и анализировать их, вы фактически загружаете данные и затем оцениваете их в контексте текущей страницы с помощью различных приемов, таких как добавление тегов сценария в документ. Это фактическая реализация Rails U JS :

processResponse = (response, type) ->
  if typeof response is 'string' and typeof type is 'string'
    if type.match(/\bjson\b/)
      try response = JSON.parse(response)
    else if type.match(/\b(?:java|ecma)script\b/)
      script = document.createElement('script')
      script.setAttribute('nonce', cspNonce())
      script.text = response
      document.head.appendChild(script).parentNode.removeChild(script)
    else if type.match(/\b(xml|html|svg)\b/)
      parser = new DOMParser()
      type = type.replace(/;.+/, '') # remove something like ';charset=utf-8'
      try response = parser.parseFromString(response, type)
  response

Это в основном то, как мы привыкли делать AJAX вызовы между доменами десять лет go с JSONP , чтобы обойти ограничения браузеров того времени.

Вы можете эмулировать то же самое в «необработанном ajax запросе» с помощью:

let xhttp = new XMLHttpRequest();
const url = "/users";
xhttp.open("POST", url);
// Some other things added to it...
xhttp.onreadystatechange = function() {
  if (this.readyState == 4 && this.status == 201) {
    let script = document.createElement('script');
    script.innerHTML = data;
    document.querySelector('head').appendChild(script);
  }
};

Но довольно честно говоря js.erb это ужасная идея. Это делает полный беспорядок в ответах на стороне сервера и клиента, и делает ваш код очень сложным для отслеживания и рассуждений, и он перемещает JS из конвейера assets / webpack в небольшую совокупность процедурных представлений нежелательного сценария. Единственная возможная причина его использования - то, насколько вы ленивы с Rails U JS и все же добавляете немного ajax в ваше приложение.

Если вы в любом случае пишете обработчик ajax, просто верните кусок html (в объекте json или как html) и вместо этого добавьте его в DOM.

...