suchen

Heim  >  Fragen und Antworten  >  Hauptteil

Weisen Sie benutzerdefinierten CSS-Eigenschaften ohne JavaScript sicher nicht vertrauenswürdige Eingaben zu: Eine Anleitung

Angenommen, ich habe ein Objekt mit Zeichenfolgenschlüsseln und Zeichenfolgenwerten und möchte diese als benutzerdefinierte CSS-Eigenschaften in einen vom Server generierten HTML-Code schreiben. Wie kann ich das sicher machen?

Was ich mit Sicherheit meine

Der Einfachheit halber beschränke ich die Tasten darauf, nur Zeichen der Klasse [a-zA-Z0-9_-] zuzulassen.

Nachdem ich die CSS-Spezifikation gelesen und einige persönliche Tests durchgeführt habe, denke ich, dass Sie große Fortschritte machen können, indem Sie die folgenden Schritte befolgen:

Ich habe mir die oben genannten Schritte basierend auf dieser CSS-Syntaxspezifikation ausgedacht

Für den Kontext können diese Eigenschaften von benutzerdefinierten Stilen verwendet werden, die wir an anderer Stelle einfügen. Das gleiche Objekt wird jedoch auch als Vorlagendaten in der Vorlage verwendet, sodass es eine Mischung aus Zeichenfolgen enthalten kann, die als Inhalt gedacht sind, und Zeichenfolgen, die als CSS-Variablen erwartet werden . Ich habe das Gefühl, dass der obige Algorithmus eine gute Balance zwischen Einfachheit schafft, ohne das Risiko einzugehen, zu viele Schlüssel-Wert-Paare wegzuwerfen, die in CSS nützlich sein könnten (und sogar zukünftige Ergänzungen zu CSS zu ermöglichen, aber ich möchte sicherstellen, dass ich das nicht tue). Es fehlt nichts


Hier ist ein JS-Code, der zeigt, was ich erreichen möchte. obj 是有问题的对象,而 preprocessPairs ist eine Funktion, die das Objekt nimmt und es vorverarbeitet, wobei die Werte wie in den obigen Schritten beschrieben entfernt/neu formatiert werden.

function generateThemePropertiesTag(obj) {
  obj = preprocessPairs(obj);
  return `<style>
:root {
${Object.entries(obj).map(([key, value]) => {
  return `--theme-${key}: ${value};`
}).join("\n")}
}
</style>`
}

Wenn man also ein Objekt wie dieses erhält

{
  "color": "#D3A",
  "title": "The quick brown fox"
}

Ich möchte, dass das CSS so aussieht:

:root {
--theme-color: #D3A;
--theme-title: The quick brown fox;
}

Obwohl --theme-title eine ziemlich nutzlose benutzerdefinierte Variable ist, wenn sie in CSS verwendet wird, beschädigt sie das Stylesheet nicht wirklich, da CSS Eigenschaften ignoriert, die es nicht versteht.

P粉356361722P粉356361722568 Tage vor809

Antworte allen(1)Ich werde antworten

  • P粉898107874

    P粉8981078742023-09-07 21:34:20

    我们实际上可能只使用正则表达式和一些其他算法,而不必依赖于一种特定的语言,希望这是您所需要的。

    通过声明对象键位于 [a-zA-Z0-9_-] 内,我们需要以某种方式解析值。

    价值模式

    因此,我们可以将其分为几类,然后看看我们会遇到什么(为了清楚起见,它们可能会稍微简化):

    1. '.*'(用撇号包围的字符串;贪婪)
    2. ".*"(用双引号括起来的字符串;贪婪)
    3. [+-]?\d+(\.\d+)?(%|[A-z]+)?(整数和小数,可选百分比或带单位)
    4. #[0-9A-f]{3,6}(颜色)
    5. [A-z0-9_-]+(关键字、命名颜色、“缓入”等内容)
    6. ([\w-]+)\([^)]+\) (类似 url()calc() 的函数> 等等)

    第一次过滤

    我可以想象在尝试识别这些模式之前您可以进行一些过滤。也许我们首先修剪值字符串。正如您所提到的, <> 可以在 preprocessPairs() 函数的开头进行转义,因为它不会出现为我们上面有的任何模式。如果您不希望在任何地方出现未转义的分号,您也可以转义它们。

    识别模式

    然后我们可以尝试识别中的这些模式,对于每个模式,我们可能需要再次运行过滤。我们期望这些模式将由一些(或两个)空白字符分隔。

    包括对多行字符串的支持应该没问题,这是一个转义的换行符。

    语言环境

    我们需要认识到我们至少要过滤两个上下文 - HTML 和 CSS。当我们在