HTMLにHTMLを含める
11829 ワード
インスパイアド
この記事についてのコメント
FJones
•
これは、htmlincludeの(かなり粗野な)メソッドの上で、ウェブコンポーネントのために非常に面白いユースケースとして私を攻撃します.jsまた、これは非常に多くのCSP問題を打つようです.例えば、含まれるファイルから任意のスクリプトタグや外部リソースを読み込むのに苦労するでしょう.
挑戦のような音!ここでは、デザインの目標です 単純な、フロントエンドのみHTML API他のHTMLドキュメント内のHTMLフラグメントを含むように HTML Boilerplateは含まれていないHTMLフラグメントに必要です.例えば、 複数の子フラグメントを問題なくレンダリングします.例えば、 一度レンダリング リソースが正しく設定されている限り、Crossヘッダーを含む ラン 動かない これ以上のADOがない場合は、実装です.
この関数を使用して、含まれる内容が同じ原点から確認されます.もしそうでなければ、サードパーティにスクリプトを注入することができないように、それは間違いなく消毒を必要とします.
例えば、
これは、必要に応じてHTMLを消毒するための関数です.
使用
Webコンポーネントそのものです.
使用によって
最後に、使用中のコンポーネントの例を示します.
読書ありがとう!どのような改善は、APIや機能になりますか?
この記事についてのコメント
HTMLの内部にHTMLを含める
サヘルカカー・ 8月7日・ 2分読む
#html
#javascript
#webdev
#programming
FJones
•
これは、htmlincludeの(かなり粗野な)メソッドの上で、ウェブコンポーネントのために非常に面白いユースケースとして私を攻撃します.jsまた、これは非常に多くのCSP問題を打つようです.例えば、含まれるファイルから任意のスクリプトタグや外部リソースを読み込むのに苦労するでしょう.
挑戦のような音!ここでは、デザインの目標です
htmlinclude.js
<div></div>
罰金-必要はありません<!DOCTYPE html><html lang="en"><head><title>title</title></head><body><div></div></body></html>
<div>1</div> <div>2</div>
だけでなく<div><div>1</div> <div>2</div></div>
does include-html
コンポーネントはDOMに存在しませんscript
同じ起源のコンテンツのタグsanitize
属性セットscript
タグまたは何か他のクロス起源のコンテンツから起源
この関数を使用して、含まれる内容が同じ原点から確認されます.もしそうでなければ、サードパーティにスクリプトを注入することができないように、それは間違いなく消毒を必要とします.
/** @param {string} src */
const isSameOrigin = (src) =>
new URL(src, window.location.origin).origin === window.location.origin
第2のパラメータを提供することによってbase
に URL
constructor , 我々は解決するsrc
現在の原点からの相対パスです.そして、origin
その二つは同じだ.例えば、
new URL('./bar.html', 'https://foo.co')
解決するhttps://foo.co/bar.html
, その中でorigin
まだhttps://foo.co
, だから結果はtrue
new URL('https://baz.co/quux.html', 'https://foo.co')
解決するhttps://baz.co/quux.html
. The base
この場合のパラメータはsrc
既に完全修飾されています.The origin
is https://baz.co
, 異なるhttps://foo.co
, だから結果はfalse
セーフHTML
これは、必要に応じてHTMLを消毒するための関数です.
/** @param {{ sanitize?: boolean } = {}} */
const safeHtml = ({ sanitize } = {}) =>
/** @param {string} html */
(html) => {
const sanitized = sanitize !== false ? DOMPurify.sanitize(html) : html
return Object.assign(sanitized, {
__html: sanitized,
})
}
使用する DOMPurify
, 広く使用され、戦いのHTMLソリューションのソリューションをテストした.使用
Object.assign
文字列でString
追加のプロパティを追加したオブジェクト.加えることによって__html
プロパティは、直接我々の結果を使用してdangerouslySetInnerHTML
我々が欲しいならば、我々はまだ要素のものにそれを直接割り当てることができますinnerHTML
, それはまだ文字列です.sort of .const result = safeHtml()('<hr/>')
result // String {"<hr>", __html: "<hr>"}
result.valueOf() // "<hr>"
'' + result // "<hr>"
Webコンポーネント
Webコンポーネントそのものです.
class IncludeHtml extends HTMLElement {
async connectedCallback() {
const forceSanitize = Boolean(this.attributes.sanitize)
const src = this.attributes.src.value
if (!this.innerHTML.trim()) {
this.textContent = 'Loading...'
}
const res = await fetch(src)
const html = safeHtml({
sanitize: !isSameOrigin(src) || forceSanitize,
})(await res.text())
const range = document.createRange()
// make rendering of fragment context-aware
range.selectNodeContents(this.parentElement)
this.replaceWith(range.createContextualFragment(html))
}
}
customElements.define('include-html', IncludeHtml)
使用 range.createContextualFragment
実行するHTMLフラグメントを作成することもできますscript
タグは、レンダリング(我々はまだ離れてそれらをsanitizedしていない仮定)に存在する.range.selectNodeContents
周囲のコンテキストを意識した方法で、レンダリングが期待通りに動作することを意味します.例えば、aを挿入しようとするとtr
テーブルの外側には何も表示されませんが、テーブル内で期待通りに動作します.使用によって
this.replaceWith
, コンテンツのレンダリングとして、DOMからWebコンポーネントをすぐに削除します.用途
最後に、使用中のコンポーネントの例を示します.
<nav>
<include-html src="./includes/nav.html"></include-html>
</nav>
<main>
<!--
Including from 3rd-party source works
(if CORS headers set properly on the source)
-->
<include-html
src="https://dinoipsum.herokuapp.com/api/?format=html¶graphs=2&words=15"
></include-html>
</main>
<footer>
<include-html sanitize src="./includes/footer.html"></include-html>
</footer>
レンダリングされた出力を見ることができ、このライブCodesandboxで自分自身を試してみましょう.読書ありがとう!どのような改善は、APIや機能になりますか?
Reference
この問題について(HTMLにHTMLを含める), 我々は、より多くの情報をここで見つけました https://dev.to/lionelrowe/include-html-in-html-an-iteration-45ikテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol