カテゴリーアーカイブ HTML

著者:杉浦

【Vue】改行とv-htmlとXSS対策

 Vue.js上で文字列を展開したい時があります。例えばそれは誰かが投稿したコメントをコンポーネント上に表示する時です。こういった時コメントの改行が反映されていない場合、見栄えが悪くなります。改行を行う必要があります。
 HTML上の改行と言えばbrタグです。PHPにはnl2brという改行コードを改行タグに変換する組み込み関数があるぐらいです。
PHP: nl2br – Manual
 改行の実現でありがちで危険なアンチパターンはこのnl2br関数を用いたコメントをそのまま表示しようと考えるものです。Vue.jsにはv-htmlというディレクティブがあり、これを用いると普段かかっている安全装置のHTMLエスケープを外し、HTMLとしてパース、実行します。brタグとv-htmlを用いることで改行コードを改行タグに変換して表示できます。
 v-htmlはXSSをまあまあ容易に招く危険性を持ちます。まあまあ危険というのは単純な

<script>alert('XSS')</script>

ぐらいならVueの仕組み上実行されず済むからです。とはいえ

<EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzdmc9Imh0dH A6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcv MjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hs aW5rIiB2ZXJzaW9uPSIxLjAiIHg9IjAiIHk9IjAiIHdpZHRoPSIxOTQiIGhlaWdodD0iMjAw IiBpZD0ieHNzIj48c2NyaXB0IHR5cGU9InRleHQvZWNtYXNjcmlwdCI+YWxlcnQoIlh TUyIpOzwvc2NyaXB0Pjwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED>

の様な多少の変化球(scriptタグをbase64形式でエンコード、埋め込んだコード中でデコードして実行)であっさり破られるのでやはり危険です。

XSS 脆弱性を容易に引き起こすので、ウェブサイトで動的に任意のHTMLを描画することは、非常に危険です。信頼できるコンテンツにだけ HTML 展開を利用してください。ユーザーから提供されたコンテンツに対しては決して使用してはいけません。

テンプレート構文 — Vue.js

 これの対策は実現したい機能に関しての実装を生のHTMLに頼るのでなく個々の別手法を用いるのが一番でしょう。
 例えば改行に関してはCSSのwhite-space実現できます。white-spaceは要素内のホワイトスペースをどう扱うか決定するスタイルであり、ホワイトスペースの一種(少なくとも正規表現の\sグループでまとめられる)である改行文字の制御もこれでできます
white-space – CSS: カスケーディングスタイルシート | MDN
 上記リンクから引用した次の表の’改行を残す’スタイルを用いれば
と生のHTML実行を用いるまでもありません。

  改行 空白とタブ文字 テキストの折り返し 行末の空白
normal まとめる まとめる 折り返す 除去
nowrap まとめる まとめる 折り返さない 除去
pre 残す 残す 折り返さない 残す
pre-wrap 残す 残す 折り返す ぶら下げ
pre-line 残す まとめる 折り返す 除去
break-spaces 残す まとめる 折り返す 折り返す
  • この記事いいね! (0)
村上 著者:村上

【JavaScript】スクロールバーをカスタマイズする方法

実際に使う機会があるかは分かりませんが、ひょんなことから調べたので備忘録としてまとめ。
Webページのスクロールバーをカスタマイズする方法です。

普通ブラウザのスクロールバーは、グレーの四角形だと思いますが、Web ページによっては、この見た目がそぐわなくて美しくない!という場合があるかと思います。
そんな時に、このスクロールバーではなくもっとシンプルなスクロールバーを実装するためのライブラリがあります。

それがこちらの「SimpleBar」というライブラリです。
公式サイトはこちらから。

SimpleBar – Custom scrollbars made simple
http://grsmto.github.io/simplebar/

 

使い方はとても簡単で、まず simplebar.min.jssimplebar.css ファイルをダウンロードして、HTML の head 内に追加します。
もしくは、CDN でも配信しているので、こちらを記述しても OK です。

<link rel="stylesheet" href="./css/simplebar.css">
<script src="./js/simplebar.min.js"></script>
<!-- または -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/simplebar@latest/dist/simplebar.css">
<script src="https://cdn.jsdelivr.net/npm/simplebar@latest/dist/simplebar.min.js"></script>

ちなみに、ReactVue.js でも使えるようです。

あとは、スクロールを追加したい要素に対して data-simplebar を追加します。
サンプルコードは下記のとおりです。

<div data-simplebar>
    <!-- 表示したい要素 -->
</div>

作業は以上です!
これでシンプルなスクロールバーが実装できます。

 

以上、ブラウザのスクロールバーをカスタマイズする方法でした。
折角調べたので、機会があれば是非実装してみたいと思います。

  • この記事いいね! (0)
著者:杉浦

色々便利なフロントエンド技術の書いてあるFrontEndHandbook2019の紹介

 昨年度までは日本語訳したものがQiitaなどどこかしら分かりやすい場所に上がっていた様なのですが、今年度は見当たらないの本元を検索。githubにありました。
FrontendMasters/front-end-handbook-2019: [Book] 2019 edition of our front-end development handbook
Front-end Developer Handbook 2019 – Learn the entire JavaScript, CSS and HTML development practice!
 FrontEndHandbookには主にJavaScript、CSS、HTMLに関連するその時々の新しい技術と発行直前の流行り、何が出来れば効率よく品質の良いフロントエンドを作れるかなどが載っています。大体の記事は短めの話とリンク集で、そういったものが集まっています。リンクの先は結構がっつりした話が多いです。
 即物的に役立つのはChapter 5. Front-end Dev Toolsです。この章には、これ便利だよ、といった編集者らのおすすめ開発ツールが載っています。有名どころが多いですが、とにかく数が多い為何かしら知らない有益なツールを見つけられます。

  • この記事いいね! (1)
著者:杉浦

Chromeのtextareaでスクロール位置の変更が上手くいかないことがある

 次のデモはVueを使ったtextarea中のクリック、キーアップ、キーダウンに反応してscrollTopを取得、表示するデモです。
 
 これを動かすと少々直感的でない動作とそのscrollTopの値が現れます。例えば次です。デモはclick, key up, key downそれぞれについていますが動画はclick, key downをまとめた一つのみです。

 screenTop:339になってからEnterを押して改行を実行すると、textareaのカーソルが画面内のてっぺんになり、screenTopが更新されません。どういうわけか度々この現象が起きます。マウスでスクロールぐりぐり、上下に余裕のある場所へクリックでカーソル配置、改行で度々再現します。
 これに近い正常な現象は次の様にすると見えます。カーソルをセット、画面外に追いやってからEnterで改行をすると、textareaのカーソルがtextarea内のてっぺんになります。こちらの場合はscrollTopが更新されます。

 この二つから推測されるのは、「何らかの原因で期待するscrollTopがとれず、仮にscrollTop=0と扱って改行を実行。正常な動作同様にtextareaのカーソルが画面内のてっぺんになるようにscrollTop変更。」という動作です。Chrome自体のコードは非公開ですし、詳しい内容はわかりませんがなかなか面白い現象です。
 余談ですがChromeのscrollTopは少数以下も取っていますがFireFox, Microsoft Edgeは少数以下を切り捨ててInt型の様に振る舞っていました。また、Operaは少数ありでした。加えてOperaもカーソルの挙動が不穏でした。少数絡みで何かしらあるのかもしれませんね。

  • この記事いいね! (0)
著者:杉浦

【HTML】ウェブブラウザのHTML補完におけるブラウザ間の差異

 ウェブブラウザはHTMLコードなどの特定の形式の文書を構文解析して画面に描画します。この構文解析の動作の大部分はW3Cが定義しており、ほぼ全てのウェブブラウザはこれに従っています。

All Standards and Drafts – W3C

 ウェブブラウザは正しいHTMLコードを正しく読み込めます。しかし世の中に公開されているwebページのHTMLコードは正しい構文でないものも多くあります。例えば、tableタグ構造が欠けているのにtdを使う、閉じタグが欠けている、です。ウェブブラウザにはその様なページも一見壊れていない様にHTMLタグを補完する機能がよく備わっています。この記事ではこのHTMLタグ補完機能について述べます。
 昨今のブラウザはJavaScriptから構文解析器を呼び出せます。

DOMParser – Web API | MDN
 これに不完全なHTMLコードを構文解析させることでHTMLタグの補完を見てみます。
 次の一つ目がIE、二つ目がChromeです。これはタグの補完が上手く働いている例です。table->tbody->tr->tdという構造が正しく作られています。
 
 次の前者がIE、後者がChromeです。これはタグの補完が上手く働いている例です。table->tbody->tr->tdという構造が改めて作られています。

<table>
  <td></td>
<!--IE-->
<html>
<head>
  <META content="IE=11.0000" http-equiv="X-UA-Compatible">
</head>
<body>
<table>
  <tbody>
    <tr>
      <td></td>
    </tr>
  </tbody>
</table>
</body>
</html>

<table>
  <td></td>
<!--Chrome-->
<html>
<head></head>
<body>
<table>
  <tbody>
    <tr>
      <td></td>
    </tr>
  </tbody>
</table>
</body>
</html>

 次の前者がIE、後者がChromeです。これはブラウザによって補完結果が異なることを示す例です。pタグ内に閉じ忘れdivタグを置くミスによって、補完結果のDOMが変わっています。IEの壊れ方は恐ろしいです。divタグのミスなのにブラウザ上のHTMLコードではpタグが壊れています。

<div>
  <p>
    <div>
  </p>
</div>
<!--IE-->
<html>
<head>
  <META content="IE=11.0000" http-equiv="X-UA-Compatible">
</head>
<body>
<div>
  <p>
    <div><p></p></div>
</div>
</body>
</html>

<div>
  <p>
    <div>
  </p>
</div>
<!--Chrome-->
<html>
<head></head>
<body>
<div>
  <p></p>
  <div><p></p></div>
</div>
</body>
</html>

 同様のコードをFirefox、Opera、Microsoft Edge、にかけたところ幸いなことに補完結果はChromeと同様でした。しかし一例ながら単純なミスでもブラウザによって補完結果が異なることがあるとわかりました。複雑なHTMLコードの場合、IE以外のブラウザが変わらず一様なHTML補完をするか少々疑問です。HTMLは不正確であっても形はどうあれブラウザ上で止まらずに動き続けます。ブラウザの補完で補いきれなくなって画面が壊れてようやくミスが明るみにでます。これを避けるためにはソースコード時点でlintにかける等の厳密な管理が必要になります。

  • この記事いいね! (1)
村上 著者:村上

【JavaScript】正規表現で文字列からHTMLのaタグを抜き出す方法

今後も絶対に使う機会があると思うので、備忘録としてまとめます。
HTMLの aタグ を正規表現で抜き出す方法についてです。
と言っても、JavaScript は match() もしくは replace() を使えばOKなので、aタグ かどうかを判断するための正規表現そのものを記載しておきます。
今後使うかもしれないものでも、こうしてメモしておかないと忘れるので…。

 

今回参考にさせていただいた記事はこちらから。

正規表現でHTMLタグを<a.*?</a>でマッチさせるのは間違っている|iwb.jp
https://iwb.jp/javasctipt-html-regexp-match/

タイトルにもある通り、aタグを <a.*?</a> という正規表現で判断するのは間違っているとのこと。
上記の正規表現でも aタグを抜き出すことはできますが、仮に addressタグがあった場合、こちらにも一致してしまうため、正しい結果にならないことがあるとのことでした。
幸い、私が開発しているプロジェクトでは、addressタグを使うことはないと思いますが、念には念を入れ、この記述方法は却下しました。

で、正しい記述がこちら。

const result = [aタグを抜き出したい文字列].match(/<a(?: .+?)?>.*?<\/a>/g);

上記を実行すれば、変数 result に文字列から抜き出した aタグが格納されます。
なお、正規表現最後の g は繰り返しマッチングを行うかどうかを指定するものです。
これがないと、もし文字列に複数の aタグがあった場合、最初の aタグだけしか抜き出さないので、もし文字列に複数の aタグが含まれ、かつそれらをすべて抜き出したい場合は、g を指定しておく必要があります。

 

以上、JavaScript の正規表現で HTML の aタグを抜き出す方法でした。
なお、今回のサンプルコードでは match() を使い、aタグを抜き出しましたが、置換を行いたい場合は replace() を用いてください。

  • この記事いいね! (0)
村上 著者:村上

AndroidやiOS端末での開発に最適なWebフォント「WebHostingHub Glyphs」

少し前からAndroid の WebView で表示されない!と悩んでいるアイコンWebフォント「WebHostingHub Glyphs」ですが、これ自体はとても多くのアイコンが提供されていて便利なのでご紹介。
あらゆるWebプロジェクトで利用しやすく、Android や iOS などモバイル端末の開発で最適とのこと。
…私の環境では一部の WebView ページで動かないんですけどね!

 

公式ページはこちら。

WebHostingHub Glyphs
https://www.webhostinghub.com/glyphs/

導入方法は、まず「How to Use」の、右サイドバーから「DOWNLOAD ALL ICONS IN ONE FONT」ボタンをクリックします。
そうすると、WebHostingHub Glyphs フォントと CSS がダウンロードできるので、これをWebフォントを追加したいプロジェクトに追加します。
そして、下記を HTML の head に追加すれば準備はOK。

<link rel="stylesheet" href="./css/whhg.css">

なお、上記のCSSファイルへのパスは環境に合わせて適宜変更してください。

あとは、アイコンWebフォントを追加したい場所に i タグ を使用してアイコンを追加します。

<i class="icon-map-marker"></i>

実行すれば、アイコンが追加されているはずです。
なお、アイコン追加時に使用するタグは、i タグ でなくてもOKみたい?

 

また、アイコンは Webフォントとしてではなく、PNG 画像としてダウンロードすることも可能です。
サイズは 32×32 もしくは 16×16 のサイズで、色は白か黒のみです。
サイズや色が環境と合えば、PNG 画像を導入してもいいかもしれません。
端末によっては、Webフォントが正常に表示されない環境もあるようですし…使えそうなら画像を使った方が確実かつ簡単かも。

 

以上、アイコンWebフォント「WebHostingHub Glyphs」のご紹介でした。
皆様、便利にご活用ください。

  • この記事いいね! (0)
村上 著者:村上

【CSS】パーセントで指定した横幅に応じた正方形のエリアを描画する

今日、後輩の作業のお手伝いをしているときに見つけた方法です。
個人的にはかなり驚きというか、こんなことできるの!?という指定方法だったので、備忘録としてまとめ。
というか、今後絶対使うときが来る気がする。

参考にさせていただいたサイトはこちらから。

横幅にあわせて正方形のエリアを作って画像を当てはめたいときの簡単なCSS – NaLabo Blog
https://www.nalabo.net/blog/2017/05/04/1009

 

実装方法ですが、まず HTML を下記のように記述します。

<div class="frame">
    <div class="content">
        <!-- 表示したい要素 -->
    </div>
</div>

で、CSS は下記のように指定します。

.content {
    width: 100%;
    height: 0;
    padding-bottom: 100%;
}

上記のように記述すると、content クラスの要素が、横幅 100% の正方形で描画されます。
ポイントは、height: 0;padding-bottom: 100%; です。
パーセント指定なので、親要素のサイズが変わっても対応できます。

正直、こんな方法があるのか…とかなり驚きでした。
なお、width: 80%; にするときは、padding-bottom: 80%; としておくと、これでも正方形になります。

 

以上、パーセントで指定された要素の横幅に応じた正方形を描画する方法でした。
かなり便利だったので、同じことでお困りの方は是非ご参考にしていただければと思います。

  • この記事いいね! (0)
村上 著者:村上

【React】テキスト要素にフォーカスが当たった/外れたときに特定の処理を実行する方法

今後も使いそうな処理なので、備忘録としてまとめ。
React で、テキスト要素にフォーカスが当たった、もしくはフォーカスが外れた事を検知し、そのときに特定の処理を実行する方法です。
なお、タイトルには React とありますが、JavaScript でも使用できます。

今回参考にさせていただいた記事はこちら。

[JavaScript] フォーカス・アウト イベントを取得する(onBlur) – コピペで使える JavaScript逆引きリファレンス
https://javascript.programmer-reference.com/js-event-onblur/

 

さて、早速コードはこちら。
必要なところだけ抜粋してます。

onFocusFunc() {
  // フォーカスが当たったときの処理
}
onBlurFunc() {
  // フォーカスが外れたときの処理
}

render() {
  return (
    <input type='text' onFocus={() => this.onFocusFunc()} onBlur={() => this.onBlurFunc()} />
  );
}

コードといってもこれだけです。
あとは各関数に、フォーカスが当たった時/外れたときの処理を記述してください。
なお、onFocusonBlur は、全て小文字ではなく、キャメルケースになっているのでお気をつけください。
素の HTML だと全て小文字なので、うっかり間違えそうです。

処理としては全く複雑なことはしていないのですが、フォーカスが外れたときに発火する onBlur を忘れそうだったので、まとめました。
onFocus はそのままの名前なのでわかりやすいのですが、onBlur って少し覚えにくい…。
なお、blur は「ぼかし」という意味があるようです。…ますますわかりにくい気がするのは私だけでしょうか…。
とにかく、忘れないように気をつけます。

 

以上、React でテキスト要素にフォーカスが当たった/外れたときに特定の処理を実行する方法でした。

  • この記事いいね! (0)
村上 著者:村上

【JavaScript】iframe内コンテンツ高さを取得する方法

今回は、JavaScript で iframe 内のコンテンツ高さを取得する方法についてです。
開発中のサービス内で、サイトのページを表示しているのですが、iframe をスクロールさせずに、さも一つのページのように見せたかったため、こちらの方法を調査しました。
そもそも、ページ内でさらにスクロールが発生すると、不便ですしね。

参考にさせていただいた記事はこちらから。

iframe内のコンテンツサイズに応じて、frameの高さを動的に変更する方法 – Qiita
https://qiita.com/Tanaaaaan/items/62df7d8ab061213aef58

2014年の記事ですが、特に問題なく動作しました。

ただし、こちらの方法は同一ドメインにあるページでしか使えないので、その点のみご注意ください。

 

さて、実装方法ですが…やっていることは、「iframe 内コンテンツの高さ取得 → iframe の高さ変更」のみです。
具体的には下記のとおり。

まず、iframe はこんな感じで指定します。

<iframe src='[ページURL]' width='100%' height='300px' frameBorder='0' scrolling='no' id='iframe' onLoad='iframeResize'></iframe>

iframe のリサイズ処理を書いた関数を onLoad に指定しています。
これにより、iframe の読み込みが完了したタイミングで、リサイズの関数が呼ばれます。

リサイズ関数はこちら。

function iframeResize() {
    const frame = document.getElementById('iframe');
    const height = frame.contentWindow.document.body.scrollHeight;
    frame.style.height = height + 'px';
}

上記を実行したところ、問題なく iframe の高さが変更されました。
枠線なし・スクロールなしなので、一枚のページのように見えます。
ただ、読み込んでいるページが原因なのか、iframe が読み込み完了になるまで結構時間がかかるので、ローディングのクルクル画像を追加するなど、読み込み中であることを表現したほうが良さそうです。

 

以上、iframe 内のコンテンツ高さを取得し、iframe 自体の高さを変更する方法でした。
参考にしていただければ幸いです。

  • この記事いいね! (1)