Подтвердить что ты не робот

Почему escape_javascript перед рендерингом частичного?

Я смотрю этот эпизод Railscast и задаюсь вопросом, зачем нужен вызов escape_javascript здесь:

$("#reviews").append("<%= escape_javascript(render(:partial => @review)) %>");

Для чего используется escape_javascript?

В соответствии с документами Rails:

escape_javascript (JavaScript)

Возврат оператора возврата и одиночный и двойные кавычки для сегментов JavaScript.

Но для меня это не значит.

4b9b3361

Ответ 1

Потому что вы не хотите, чтобы пользователи отправляли JavaScript, который фактически выполняет браузер?

Ответ 2

Легче понять, разделите ли вы код на две части.

Первая часть $("#reviews").append("<%= ... %>"); - это javascript с erb. Это означает, что <%= ... %> будет заменен тем, что возвращает код Ruby внутри. Результатом этой замены должен быть действительный javascript, иначе он выдает ошибку, когда клиент пытается ее обработать. Итак, первое: вам нужен действительный javascript.

Еще одна вещь, которую следует учитывать, - это то, что любой Ruby генерирует, должен содержаться внутри строки javascript с двойными кавычками - обратите внимание на двойные кавычки вокруг <%= ... %>. Это означает, что сгенерированный javascript будет выглядеть следующим образом:

$("#reviews").append("...");

Теперь рассмотрим рубиновую часть внутри <%= ... %>. Что делает render(:partial => @review)? Это рендеринг частичного - это означает, что он может быть рендерингом любого типа кода - html, css... или даже больше javascript!

Итак, что произойдет, если наша часть содержит простой html, как этот?

<a href="/mycontroller/myaction">Action!</a> 

Помните, что ваш javascript принимал строку с двумя кавычками в качестве параметра? Если мы просто заменим <%= ... %> кодом этого частичного, то у нас есть проблема - сразу после href= существует двойная кавычка! Javascript недействителен:

// Without escaping, you get a broken javascript string at href
$("#reviews").append("<a href="/mycontroller/myaction">Action!</a>");

Чтобы этого не произошло, вы хотите избежать этих специальных символов, чтобы ваша строка не была вырезана - вам нужно что-то, что генерирует это вместо:

<a href=\"/mycontroller/myaction\">Action!</a>

Это то, что делает escape_javascript. Он гарантирует, что возвращенная строка не "сломает" javascript. Если вы его используете, вы получите желаемый результат:

$("#reviews").append("<a href=\"/mycontroller/myaction\">Action!</a>")

Привет!

Ответ 3

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

попробуйте следующее:

<% variable = '"); alert("hi there' %>
$("#reviews").append("<%= variable %>");

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

Ответ 4

Если вы посмотрите на источник здесь, это будет намного понятнее.

Эта функция выполняет следующие две функции:

  • Он заменяет символы во входной строке теми, что определенный в JS_ESCAPE_MAP

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

  • Функция также проверяет, является ли результирующая строка html безопасной. Если это не так, это делает необходимое ускорение, чтобы убедиться, что строка становится html безопасной и возвращает результат.

Когда вы используете escape_javascript, он обычно внедряется в другую строку или существующий html динамически. Вы должны убедиться, что это не сделает вашу страницу не рендеринга.

Некоторые аспекты этого ответа были отмечены в других ответах, но я хотел собрать все элементы вместе, включая разницу между экранированием javascript и html-экранированием. Кроме того, в некоторых ответах указывается, что эта функция помогает избежать инъекции script. Я не думаю, что это цель этой функции. Например, в своем обзоре, если в вашем отзыве есть предупреждение ( "привет там" ), просто добавление его в node не приведет к всплытию. Вы не встраиваете его в функцию, которая запускается при загрузке страницы или через какое-то другое событие. Простое оповещение ( "привет там" ) как часть вашего html не означает, что он будет выполняться как javascript.

Это говорит о том, что я не отрицаю, что инъекция script невозможна. Но чтобы избежать этого, вам нужно предпринять шаги, когда вы берете пользовательские данные и храните их в своей базе данных. Функция и пример, которые вы предоставляете, связаны с предоставлением уже сохраненной информации.

Надеюсь, это поможет и ответит на ваш вопрос.

Ответ 5

Он не выполнит javascript того, что вы показываете