Почему ru_ to_json нарушает встроенный JavaScript? - PullRequest
3 голосов
/ 05 февраля 2012

Проблема

В PHP я бы сделал это

<html>
<body>
    <script>
        <?php
        $templates = array(
          'result' => file_get_contents('template.html')
          );
          echo '__templates = ' . json_encode($templates) . ';';
          ?>
    </script>
</body>
</html>

Итак, я сделал это в Sinatra

<!DOCTYPE html>
<html>
<body>
    <script type="text/javascript">
        __templates = <%= get_templates  %>;
    </script>
</body>
</html>

И мой файл маршрутов Sinatra выглядит следующим образом:

require 'sinatra'
require 'json'
require 'erb'

helpers do
    def get_templates
        {'result' => (erb :template2)}.to_json
    end
end

get '/' do
    erb :index
end

Но мой объект javascript в итоге ломается, когда я использую объект __templates из jquery.

Что делает to_json в ruby, а PHP - нет?

php result

{"result":"<!doctype html>\n<html>\n\n<head>\n\t<meta charset=\"UTF-8\">\n\t<title>{{ TITLE }}<\/title>\n\n\t<style type=\"text\/css\">\n\t{{ CSS }}\n\t<\/style>\n<\/head>\n\n<body>\n\n\t{{{ HTML }}}\n\n\t<script src=\"{{{ JSLIB }}}\"><\/script>\n\t<script src=\"{{{ PREFIX }}}\"><\/script>\n\t<script>\n\t\tfunction __run() {\n\t\t\t{{{ JS }}}\n\t\t}\n\t<\/script>\n\n<\/body>\n\n<\/html>"}

ruby ​​result

{"result":"<!doctype html>\n<html>\n\n<head>\n    <meta charset=\"UTF-8\">\n    <title>{{ TITLE }}</title>\n\n    <style type=\"text/css\">\n        {{ CSS}}\n    </style>\n</head>\n\n<body>\n\n    {{{ HTML }}}\n\n    <script src=\"{{{ JSLIB }}}\"></script>\n    <script src=\"{{{ PREFIX }}}\"></script>\n    <script>\n        function __run() {\n            {{{ JS }}}\n        }\n    </script>\n\n</body>\n\n</html>\n"};

обратите внимание на <\/body> в версии php.

Решение (на данный момент)

Я нашел решение на основе комментариев, размещенных ниже.Тем не менее, я не уверен, что это «единственно верный путь», если таковой существует. ПРИМЕЧАНИЕ : Я хотел бы знать, не нарушит ли эта реализация что-то еще в будущем.Я буду зависеть от этой функции во всем приложении.

Я просто использовал gsub для решения своей проблемы.Я обернул его в помощник вот так

helpers do
    def close embedded_json
        embedded_json.gsub('</', '<\/')
    end
    ...
end

и назвал так

__templates = <%= close get_templates  %>;

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

Ответы [ 3 ]

2 голосов
/ 05 февраля 2012

Все дело в этих обратных слешах.

В любом месте в JSON появляется что-то вроде </title>, оно должно быть на самом деле <\/title>

Проблема в том, что .to_json не добавляет эти обратные слеши.

Как мы можем это сделать?

0 голосов
/ 05 февраля 2012

Я думаю, что проблема не в том, что json не является json (нет ничего плохого в / в строке json), а в том, что вы находитесь внутри html-документа, и поэтому символы типа </ имеют особое значение.

Я полагаю, что анализатору HTML кажется, что это хитрая попытка закрыть фактический тег body в вашем документе. Если вы заключите JSON с разделом CDATA, то есть

<script type="text/javascript">
//<![CDATA[
  <%= get_templates %>
//]]>
</script>

Тогда парсер HTML будет знать, что этого не делать. В Синатре вполне могут быть помощники, которые уже могут это сделать

0 голосов
/ 05 февраля 2012

Это может быть излишним, но когда я работал с Rails, используя to_json, я ненавидел это и нашел RABL https://github.com/nesquena/rabl.

Тебе стоит взглянуть на это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...