Да, избегайте слинга строк HTML. Вы получаете ошибки и потенциально дыры в безопасности межсайтовых скриптов. Например:
'<a href="'+img.parent().attr('href')+'">'
что если URL в родительском href
содержит символы, которые являются особыми в этом контексте HTML, например <
, "
или &
? В лучшем случае вы получите недопустимую разметку, которая может сбить браузер; в худшем случае, если URL-адрес поступает от пользователя, возникает проблема безопасности.
(ОК, <
и "
вряд ли появятся в URL, но очень вероятно, что &
. title
, который вы вводите в текстовое содержимое, может быть более уязвимым.)
Это большая и возрастающая проблема. Так же, как мы начинаем понимать, как исправлять ошибки HTML-инъекций, возникающие из-за шаблонов на стороне сервера (например, пользователи PHP забывают о htmlspecialchars()
), мы теперь представляем множество новых client- side XSS от наивного HTML-хакерства с innerHTML
и jQuery's html()
. Избегайте.
Вы можете экранировать текст, который вы вставляете в HTML вручную:
function encodeHTML(s) {
return s.replace(/&/g, '&').replace(/</g, '<').replace(/"/g, '"');
}
'<a href="'+encodeHTML(img.parent().attr('href'))+'">'
но на самом деле вам лучше использовать свойства и методы прямого DOM-стиля, которые, поскольку они не включают в себя HTML-разбор, не требуют экранирования. Они называются DOM-style, потому что так работают оригинальные функции HTML DOM Level 1 (которые существовали еще до того, как innerHTML
поднял свою уродливую голову):
var a= document.createElement('a');
a.href= this.parentNode.href;
a.appendChild(document.createTextNode(this.title));
В jQuery вы используете attr()
и text()
, чтобы сделать то же самое:
var a= $('<a></a>');
a.attr('href', $(this).parent().attr('href');
a.text($(this).attr('title'));
А в jQuery 1.4 вы можете сделать это наиболее удобно, используя ярлык создания элемента:
$(this).append(
$('<p class="cap"></p>').append(
$('<a></a>', {
href: $(this).parent().attr('href'),
text: $(this).attr('title')
})
)
);
Это все еще выглядит немного сомнительно, но от какого родителя вы получаете href
? Неправильно помещать <p>
или другую ссылку внутри ссылки.