По вопросу «что мне делать с этим» может быть много ответов.
Более «формальный» способ предотвращения таких ошибок при разработке применяя дизайн по контракту в вашем коде. Это означает, что при разработке вы должны установить инварианты класса и / или даже предпосылки для функции и .
Короче говоря, инварианты класса гарантируют, что в вашем классе будут некоторые ограничения, которые не будут нарушены при нормальном использовании (и, следовательно, класс будет not получить в несогласованном состоянии). Предпосылки означают, что данные, данные как входные данные для функции / метода, должны соответствовать установленным ограничениям и никогда не нарушать их, а постулаты означают, что вывод функции / метода должен соответствовать установленным ограничениям снова не нарушая их. Условия контракта никогда не должны нарушаться во время выполнения программы без ошибок, поэтому дизайн по контракту проверяется на практике в режиме отладки, а отключен в выпусках , чтобы максимизировать развитую производительность системы.
Таким образом, вы можете избежать случаев NullReferenceException
, которые являются результатом нарушения установленных ограничений. Например, если вы используете свойство объекта X
в классе, а затем попытаетесь вызвать один из его методов, а X
имеет нулевое значение, то это приведет к NullReferenceException
:
public X { get; set; }
public void InvokeX()
{
X.DoSomething(); // if X value is null, you will get a NullReferenceException
}
Но если вы установите «свойство X никогда не должно иметь нулевого значения» в качестве предпосылки для метода, вы можете предотвратить описанный ранее сценарий:
//Using code contracts:
[ContractInvariantMethod]
protected void ObjectInvariant ()
{
Contract.Invariant ( X != null );
//...
}
По этой причине Код Контракт существует для приложений .NET.
В качестве альтернативы дизайн по контракту может быть применен с использованием утверждений .
ОБНОВЛЕНИЕ: Стоит отметить, что этот термин был придуман Бертраном Майером в связи с его дизайном языка программирования Эйфеля .
Я использую следующий метод:
function htmlDecode(input){
var e = document.createElement('div');
e.innerHTML = input;
// handle case of empty input
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
htmlDecode("<img src='myimage.jpg'>");
// returns "<img src='myimage.jpg'>"
В основном я создаю элемент DOM программно, назначаю кодированный HTML его внутреннемуHTML и извлекаю nodeValue из текстового узла, созданного при вставке innerHTML. Поскольку он просто создает элемент, но не добавляет его, HTML-код сайта не изменяется.
Он будет работать с кросс-браузером (включая более старые браузеры) и принимать все элементы символов HTML .
EDIT: старая версия этого кода не работала на IE с пустыми вводами, о чем свидетельствует здесь, в jsFiddle (просмотр в IE). Версия выше работает со всеми входами.
UPDATE: похоже, что это не работает с большой строкой, а также представляет уязвимость безопасности, см. Комментарии.
Хитрость заключается в использовании мощности браузера для декодирования специальных символов HTML, но не позволяет браузеру выполнять результаты, как если бы это был фактический html ... Эта функция использует регулярное выражение для идентификации и замены закодированных символов HTML , по одному символу за раз.
function unescapeHtml(html) {
var el = document.createElement('div');
return html.replace(/\&[#0-9a-z]+;/gi, function (enc) {
el.innerHTML = enc;
return el.innerText
});
}
Если вы используете jQuery:
function htmlDecode(value){
return $('<div/>').html(value).text();
}
В противном случае используйте Объект кодирования строгого программного обеспечения , который имеет отличную функцию htmlDecode()
.
Это лучше:
String::decode = ->
$('<textarea />').html(this).text()
use:
"<img src='myimage.jpg'>".decode();
from: HTML Entity Decode
html()
небезопасен, независимо от того, где вы его используете.
– Wladimir Palant
29 August 2017 в 06:57
Все остальные ответы здесь имеют проблемы.
Методы document.createElement ('div') (включая те, которые используют jQuery) выполняют любой переданный в него javascript (проблема безопасности) и DOMParser. Метод parseFromString () обрезает пробелы. Вот чистое решение javascript, у которого нет ни одной проблемы:
function htmlDecode(html) {
var textarea = document.createElement("textarea");
html= html.replace(/\r/g, String.fromCharCode(0xe000)); // Replace "\r" with reserved unicode character.
textarea.innerHTML = html;
var result = textarea.value;
return result.replace(new RegExp(String.fromCharCode(0xe000), 'g'), '\r');
}
TextArea используется специально, чтобы избежать выполнения кода jscript. Он передает следующее:
htmlDecode('<& >'); // returns "<& >" with non-breaking space.
htmlDecode(' '); // returns " "
htmlDecode('<img src="dummy" onerror="alert(\'xss\')">'); // Does not execute alert()
htmlDecode('\r\n') // returns "\r\n", doesn't lose the \r like other solutions.
Не прямой ответ на ваш вопрос, но не лучше ли, чтобы ваш RPC мог вернуть некоторую структуру (будь то XML или JSON или что-то еще) с этими данными изображения (URL-адреса в вашем примере) внутри этой структуры?
Затем вы можете просто проанализировать его в своем javascript и построить <img>
с помощью самого javascript.
Структура, которую вы получаете из RPC, может выглядеть так:
{"img" : ["myimage.jpg", "myimage2.jpg"]}
Я думаю, что это лучше, потому что ввод кода, который поступает из внешнего источника на вашу страницу, выглядит не очень безопасным. Imaging кто-то захватил ваш XML-RPC-скрипт и поставил что-то, чего вы не хотели бы там (даже некоторые javascript ...)
htmlDecode("<img src='myimage.jpg'><script>alert('xxxxx');</script>")
, и ничего не произошло. Я получил декодированную строку html как ожидалось.
– Roatin Marth
16 December 2009 в 22:05
Крис отвечает хорошо и amp; но он терпит неудачу, если значение undefined . Простое улучшение делает его твердым:
function htmlDecode(value) {
return (typeof value === 'undefined') ? '' : $('<div/>').html(value).text();
}
return (typeof value !== 'string') ? '' : $('<div/>').html(value).text();
– SynCap
26 June 2017 в 08:09
Я использую это в своем проекте: вдохновленный другими ответами , но с дополнительным безопасным параметром, может быть полезен, когда вы имеете дело с украшенными символами
var decodeEntities=(function(){
var el=document.createElement('div');
return function(str, safeEscape){
if(str && typeof str === 'string'){
str=str.replace(/\</g, '<');
el.innerHTML=str;
if(el.innerText){
str=el.innerText;
el.innerText='';
}
else if(el.textContent){
str=el.textContent;
el.textContent='';
}
if(safeEscape)
str=str.replace(/\</g, '<');
}
return str;
}
})();
И он полезен например:
var label='safe <b> character éntity</b>';
var safehtml='<div title="'+decodeEntities(label)+'">'+decodeEntities(label, true)+'</div>';
Большинство ответов, приведенных здесь, имеют огромный недостаток: если строка, которую вы пытаетесь преобразовать, не доверяет, вы получите уязвимость Cross-Site Scripting (XSS) . Для функции в принятом ответе рассмотрим следующее:
htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");
Строка здесь содержит неэкранированный HTML-тег, поэтому вместо декодирования ничего функция htmlDecode
будет на самом деле запустить код JavaScript, указанный внутри строки.
Этого можно избежать, используя DOMParser , который поддерживается в всеми современными браузерами :
function htmlDecode(input)
{
var doc = new DOMParser().parseFromString(input, "text/html");
return doc.documentElement.textContent;
}
// This returns "<img src='myimage.jpg'>"
htmlDecode("<img src='myimage.jpg'>");
// This returns ""
htmlDecode("<img src='dummy' onerror='alert(/xss/)'>");
Эта функция не гарантирует, что какой-либо код JavaScript не будет работать как побочный эффект. Любые теги HTML будут проигнорированы, будет возвращен только текстовый контент.
Замечание о совместимости : для анализа HTML с DOMParser
требуется, по крайней мере, Chrome 30, Firefox 12, Opera 17, Internet Explorer 10, Safari 7.1 или Microsoft Edge. Таким образом, все браузеры без поддержки проходят мимо EOL, и по состоянию на 2017 год единственными, которые по-прежнему могут встречаться в дикой природе, являются более старые версии Internet Explorer и Safari (как правило, они все еще недостаточно многочисленны, чтобы беспокоиться).
DOMParser
не поддерживал "text/html"
до Firefox 12.0, а все еще есть некоторые последние версии браузеров, которые даже не поддерживают DOMParser.prototype.parseFromString()
. Согласно вашей рекомендации, DOMParser
все еще является экспериментальной технологией, а в режиме ожидания используется свойство innerHTML
, которое, как вы также указали в ответ на мой подход , имеет эту уязвимость XSS ( которые должны быть исправлены поставщиками браузеров).
– PointedEars
28 February 2016 в 09:53
<script>
, которые не выполняются, не являются механизмом безопасности, это правило просто избегает сложных проблем синхронизации, если установка innerHTML
может запускать синхронные скрипты в качестве побочного эффекта. Санитарный код HTML - это сложное дело, а innerHTML
даже не пытается - уже потому, что веб-страница может на самом деле намереваться установить встроенные обработчики событий. Это просто не механизм, предназначенный для небезопасных данных, полная остановка.
– Wladimir Palant
7 August 2016 в 14:48
'
не принадлежит к элементам HTML 4, вот почему! w3.org/TR/html4/sgml/entities.html fishbowl.pastiche.org/2003/07/01/the_curse_of_apos – CMS 16 December 2009 в 06:48