- ベストアンサー
Blobを使った画像と動画の識別方法
- WordPressでのファイルアップロード機能を検討中。
- 画像と動画の識別が課題であり、Data URIとBlob URLの表示方式について考察。
- 特に動画の表示をブラウザの対応によって避けるべきと述べている。
- みんなの回答 (19)
- 専門家の回答
質問者が選んだベストアンサー
・※別の方から頂いたアドバイス これは空にする方法ですよね。 私が修正した文字を出力する方法とは話しが違いますよね。 空にする方法は最も簡単な方法でいいと思います。 私個人的にはinnerHTMLがいいです。 別の方のアドバイスでなら1でいいと思います。 2と3の方法は、たぶんですが、名前、コメント、画像、スタンプを別々に削除していく方法で無駄な処理です。
その他の回答 (18)
- dell_OK
- ベストアンサー率13% (766/5720)
・ノードの種類はどちらに分類されると思われますでしょうか? 何の話しかわかりませんが、何を気にされているのでしょうか。 confirm_areaはdivタグなのでこれ自身は要素ノードです。 その中に、さらにdivタグやpタグやinputタグやvideoタグを追加しています。 これらもすべて要素ノードです。 テキストノードは、pタグの中に追加したテキストだけです。 空にしているのは、confirm_areaの中のすべてです。 削除対象となっているのは要素ノードもテキストノードもなにもかもです。 ノードを探して個別に指定して削除する方法ではないので、ノードを気にしなくていいと思います。
補足
申し訳ありません間違えて回答 No.17 の方に補足してしまいました。 回答ありがとうございます、dell_ok さんにアドバイス頂いたように修正するのが最善だと自分も思っていたのですが、別の方に子ノードによって対応を変えたほうがいいのではないかと教えて頂いたので迷っております… ※ dell_ok さんから頂いたアドバイス ----修正前 child.innerHTML = "名前:" + namae_value; ----修正後 child.textContent = "名前:" + namae_value; ---- ※別の方から頂いたアドバイス (1) element.childNodes がテキストノードのみ element.textContent = ''; (2) element.childNodes にテキストノード以外(要素ノード等)がある element.childNodes を remove(), removeChild() (3) 子ノードが単一なら、element.removeChild(element.firstChild)
- dell_OK
- ベストアンサー率13% (766/5720)
これだけでよかったです。 ----修正前 child.innerHTML = "名前:" + namae_value; ----修正後 child.textContent = "名前:" + namae_value; ----
補足
A.回答ありがとうございます、dell_ok さんにアドバイス頂いたように修正するのが最善だと自分も思っていたのですが、別の方に子ノードによって対応を変えたほうがいいのではないかと教えて頂いたので迷っております… ※ dell_ok さんから頂いたアドバイス ----修正前 child.innerHTML = "名前:" + namae_value; ----修正後 child.textContent = "名前:" + namae_value; ---- ※別の方から頂いたアドバイス (1) element.childNodes がテキストノードのみ element.textContent = ''; (2) element.childNodes にテキストノード以外(要素ノード等)がある element.childNodes を remove(), removeChild() (3) 子ノードが単一なら、element.removeChild(element.firstChild)
- dell_OK
- ベストアンサー率13% (766/5720)
・createTextNode を使うのが適切な気もするのですが、選択されたスタンプやアップロードされた画像や動画や PDF はテキストノードに該当するのか分からず悩んでおります。 テキスト(文字)だけを出力するならテキストノード(createTextNode=textContent)を使うのが適切だと思います。 スタンプや画像はタグそのものなのでテキストノードには該当しないと思っていただいていいと思います。 ・p タグを残したまま Textノードを作る方法にする方法はありますでしょうか? ----修正前 child.innerHTML = "名前:" + namae_value; ----修正後 child.appendChild(document.createTextNode("名前:" + namae_value)); ---- ・textContent で代用できるのではないかと思い変更してみました… 役割として間違いだと思われますでしょうか? 参考サイトにはこう書かれていますね。 「対象の要素のinnerHTMLプロパティ(textContentプロパティでも可)に空文字を代入する方法もあります」 https://qiita.com/KDE_SPACE/items/3c4b52d077b8eabbe670#%E8%A6%81%E7%B4%A0%E3%81%AE%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E5%AD%90%E3%83%8E%E3%83%BC%E3%83%89%E3%82%92%E5%89%8A%E9%99%A4 「textContentプロパティでも可」なのでどちらを使っても大丈夫そうです。 試してみると、textContentを空にすることで、その直後にはinnerHTMLも空になっているようなので、代用はできるみたいです。 役割として間違いとまでは思いませんが、空にするだけの処理にセキュリティは関係ありませんのでinnerHTMLでいいと思います。
補足
Q.p タグを残したまま Textノードを作る方法にする方法はありますでしょうか? A.修正ありがとうございます、Node の種類についてブラウザの検証ツールで調べてみたところ nodeType: 1 で ELEMENT_NODE に該当しているようです。 参考サイトに記載されている情報によりますと、テキストノードは Text, 要素ノードは Element や、コメントノードは Comment だと思われるため全て要素ノードに分類されるようです。 テキストノードに含まれるかツリー構造を理解できていない為わからないのですが、ノードの種類はどちらに分類されると思われますでしょうか? ノードの種類に応じたおすすめの方法が3つあるようです。 (1) element.childNodes がテキストノードのみ element.textContent = ''; (2) element.childNodes にテキストノード以外(要素ノード等)がある element.childNodes を remove(), removeChild() (2) 子ノードが単一なら、element.removeChild(element.firstChild) ※ノードの種類について https://qiita.com/KDE_SPACE/items/e21bb31dd4d9c162c4a6 ※nodeType を調べる方法 https://qiita.com/andota05/items/a2292d2b7780ed5faa31 ※dell_ok さんが作成されたサンプルサイト http://oksample.starfree.jp/%E8%B3%AA%E5%95%8F%E6%8E%B2%E7%A4%BA%E6%9D%BF/ ※nodeType プロパティ https://developer.mozilla.org/ja/docs/Web/API/Node/nodeType ※分類についての記載 https://ja.javascript.info/basic-dom-node-properties Q.役割として間違いとまでは思いませんが、空にするだけの処理にセキュリティは関係ありませんのでinnerHTMLでいいと思います。 A.アドバイスありがとうございます、確かに以前いただいたアドバイスでも空にする場合 innerHTML でも問題ないとのことでした。 忘れていたようです申し訳ありません。
- dell_OK
- ベストアンサー率13% (766/5720)
・今回のコードでも役割は同じだと思われますでしょうか? 同じですね。 ・68行目とは別に HTMLElement.innerHTML が9箇所使われていて~ pタグを作る方法から、Textノードを作る方法に変えましょう。 ----修正前 child = document.createElement("p"); child.innerHTML = "名前:" + namae_value; ----修正後 child = document.createTextNode("名前:" + namae_value); ---- コメントも同じようにしてみてください。
補足
A.アドバイスありがとうございます。 HTMLElement.innerHTML の役割が3通りあるようで、値を置き換えるもの、要素を空にするもの、ノード生成するものが存在するようです。 createTextNode を使うのが適切な気もするのですが、選択されたスタンプやアップロードされた画像や動画や PDF はテキストノードに該当するのか分からず悩んでおります。 子ノードにテキストノードのみが存在するなら textContent を採用、それ以外は remove, removeChild を採用するのが適切だとアドバイスを頂きました。 dell_ok さんにアドバイス頂いた方法で修正したかったのですが、p タグを残したまま Textノードを作る方法にする方法はありますでしょうか? CSS を変更する際に HTML タグをつけておきたい為、可能であれば残しておきたいと考えております。 142,198,231行目の要素を空にするものは createTextNode で書く方法が分からなかったため、 textContent で代用できるのではないかと思い変更してみました… 役割として間違いだと思われますでしょうか? ※参考サイト https://qiita.com/KDE_SPACE/items/3c4b52d077b8eabbe670 ※最新コード https://wandbox.org/permlink/miUZ9wCkcXMgrgIg
- dell_OK
- ベストアンサー率13% (766/5720)
githubにアップロードしました。 https://github.com/dell-GH/sample_theme
お礼
申し訳ありません document.addEventListener でセキュリティ対策する際に修正したコードが抜けておりました。 ※修正前のコード function lengthCheck() { const left = this.dataset.maxlength - this.value.length; if (left >= 0) { this.nextElementSibling.innerHTML = 'あと<strong>' + left + '</strong>文字'; this.dataset.submit_disabled = this.value.length === 0; } else { this.nextElementSibling.innerHTML = '<strong>' + -left + '</strong>文字超過しています'; this.dataset.submit_disabled = true; } let disabled = false; for (let i = 0; i < length_input.length; i++) { if (length_input[i].dataset.submit_disabled === "true") { disabled = true; } } submit_button.disabled = disabled; } ※修正後のコード /* 文字数表示 */ document.addEventListener('input', e => { if (!['name', 'message'].includes(e.target.id)) return; const t = e.target, m = t.nextElementSibling, n = t.value.length - (t.dataset.length | 0), c = document.createElement('span'); c.append(Math.abs(n)); m.style.color = n > 0 ? 'red' : 'black'; m.replaceChildren(n > 0 ? '' : '残り', c, `文字${n > 0 ? '超過してい' : '入力でき'}ます。`); /* 毎回判定によるボタン制御 */ validation(); }); /* 初回判定のボタン制御 */ validation(); }; window.addEventListener("load", init);
補足
コード一覧ありがとうございます。返事が遅くなり申し訳ありません。全体のコードを調べた際に意図が分からないところはなかったのですが、 画面還移する掲示板を作成した際に Javascript のセキュリティについて調べたものと同じく DOM-based XSS の発生源となる innerHTML 等修正が必要な部分がありそうです。 前回修正した際に viewer[i].innerHTML = ""; は(68行目)値をクリアしているだけとの理由でそのまま使っており、今回のコードでも役割は同じだと思われますでしょうか? 68行目とは別に HTMLElement.innerHTML が9箇所使われていて、修正方法として Document.createTextNode を代用するか document.addEventListener でまとめるか悩んでいるのですが、document.addEventListener でまとめる場合範囲をどこからどこまで囲うべきか分からず Document.createTextNode でまとめる方法も参考サイトに記載されているコードと形が異なるため止まっております… Javascript コードになるのですがアドバイスよろしくお願い致します。 ※現在のコード https://wandbox.org/permlink/uubaU6RQvGtJGZaW ※参考サイト ※DOM-based XSSについて https://gihyo.jp/dev/serial/01/javascript-security/0006 ※クロスサイトスクリプティング対策 https://atmarkit.itmedia.co.jp/ait/articles/1312/17/news010_2.html https://atmarkit.itmedia.co.jp/ait/articles/1312/17/news010_2.html
- dell_OK
- ベストアンサー率13% (766/5720)
あああ。 これはWordPressがヘッダー(<head>タグ内)につけているものです。 get_header(); を使うとそのへんのスクリプトやスタイルシートが出力されるようです。
補足
回答ありがとうございます、そうだったんですね勘違いしておりました。 Javascript コードと PHP コードがわからないのですが、wandbox か github に載せて頂くことは可能でしょうか…?
- dell_OK
- ベストアンサー率13% (766/5720)
・差し支えなければお聞きしたいのですが、そちらのソース元は分かりますでしょうか? このコードであってますか。 https://wandbox.org/permlink/dRvZsS8Lw6F7ysOq このコードは初めて見たものでまったくわかりません。
補足
回答ありがとうございます、コードで分からないところが多数あった為改行しておりました。申し訳ありません。 dell_okさんに作っていただいたサンプルページのソースからJavascript部分を抜き出した部分になります。 ※サンプルページ http://oksample.starfree.jp/%E8%B3%AA%E5%95%8F%E6%8E%B2%E7%A4%BA%E6%9D%BF/ ※該当コード https://wandbox.org/permlink/kqi7TBXCZB2XLWSB
- dell_OK
- ベストアンサー率13% (766/5720)
・教えて頂いたコードで分からないところがたくさんあり理解できずに進めるのは不安なため意味を教えて頂きたいです これは私のコードではないので説明できません。 書かれた人に聞いた方がいいと思います。 ・typeof x === 'undefined'の意味を調べた際に気になる記事を発見致しました、変更したほうがよいのでしょうか? どうでしょうね。 こう言うのは誤動作しなければ好みの話しだと思います。
補足
回答ありがとうございます、差し支えなければお聞きしたいのですが、そちらのソース元は分かりますでしょうか? githuub で公開されたコードでしょうか?
- dell_OK
- ベストアンサー率13% (766/5720)
・videoタグで動画のサムネイルが表示されないときの対処法として時間を指定してサムネイルを設定する方法があるようです ありがとうございます。 #t=0.1 を付加してみました。 確認してみてください。
補足
修正ありがとうございます、サムネイルを確認することが出来ました。 教えて頂いたコードで分からないところがたくさんあり理解できずに進めるのは不安なため意味を教えて頂きたいです、よろしくお願い致します。 ※dell_okさんに教えて頂いたコード https://wandbox.org/permlink/dRvZsS8Lw6F7ysOq 8行目は動画の時間を取得するコードでしょうか? 11行目は localStorage でオブジェクトや値を JSON 文字列に変換したデータを保存するコードでしょうか? 13行目は動画の領域を生成しているのでしょうか…? 15行目はアップロードされた画像を描画しているのでしょうか?Uint32Arrayが調べても分からず画像をデータから作り出しているコードではないかと思いました。 17行目は .clearRect() の意味が理解できず、 ctx.fillText() でテキストをCanvasに描画するという意図も分からずテキストがどの部分に使われているのか疑問に思っております。どのような機能になるのでしょうか? 22行目と24行目はどのような意味があるのでしょうか? 26行目と27行目は入力フォームをブラウザー上でサーバー処理を行うコードでしょうか? OffscreenCanvasを使用すると、Canvasへの描画負荷が高い場合でもスムーズなユーザー操作とCSSアニメーションの再生を実現できるということは調べて分かったのですが、 return e.forEach(function(e){o[e]=t(a,e,n)}),o} はどういう意味になるのでしょうか…? 29行目は動的なHTML要素作成して非同期処理の完了もしくは失敗を判定し、DOMが特定の機能をサポートしているかを確認後DOMツリー読み込み完了後に発火するという事でしょうか? 31行目はsessionStorage に保存されたJSONデータを文字列に変換、もしオブジェクトが番号となる値のデータ型を表す文字列を返す?timestampは日時の記録だと思うのですが、条件はどのようなものになるのでしょうか?番号というのは選択されたスタンプのことだと考えております。 33行目は数値を文字列化していることは分かったのですが、.createObjectURLを使ってURLを生成?する意図が分かりませんでした(画面還移しない場合URLは切り替わらない為 )。 33行目は自動で書き出される絵文字用のコードでしょうか?.everythingExceptFlagというコードを調べても意味が出てこずdell_okさんが意図して書いたコードではなく自動で挿入されたものではないかと考えております。 ____________________________________ 上記の質問とは別になるのですがtypeof x === 'undefined'の意味を調べた際に気になる記事を発見致しました、変更したほうがよいのでしょうか? //JavaScriptでtypeof x === 'undefined'を使わないで欲しい理由 https://www.ncaq.net/2018/06/16/16/44/31/
- dell_OK
- ベストアンサー率13% (766/5720)
・スマートフォンでページを開いたところ動画が表示されておりませんでした… 私の手元にある端末で確認してみました。 iPhone:表示されない iPad:表示される Androidのスマートフォン:表示される iPhoneだけが表示されないのですが、古いiPhone 6 Plusなのでそのせいかも知れません。 正確には、真っ白で動画(videoタグ)は表示されているけど最初のコマ画像が表示されていないようで、タップすると再生できました。 100pxで表示領域が小さすぎたためか、操作コントロールも表示されていないので、200pxにしてみました。 プレイボタンは表示されたので、そこに動画があることはわかるようになりました。 質問者さまのスマートフォンのOSがどちらのものかわかりませんが、同じようにプレイボタンだけでも表示されるようになりましたか。
補足
A.回答ありがとうございます、iPhone SE で確認したところタップするとプレイボタンは表示されているようです。 確認不足でした、申し訳ありません。 videoタグで動画のサムネイルが表示されないときの対処法として時間を指定してサムネイルを設定する方法があるようですが、プレイボタンのみだと認識ができない場合もありそうですので、こちらの方法で設定するのはどうでしょうか? ※参考サイト https://qiita.com/mtoutside/items/3210f24232345d75829d
- 1
- 2
お礼
アドバイスありがとうございます、役割をよく理解できずに dell_ok さんにお聞きしておりました、申し訳ありません。 innerHTML を使う場合要素を空にする場合を除いて HTML のエスケープ処理を行い後の改修にて脆弱性が生まれる余地をなくすべきだとアドバイスを頂いておりました。 Document.createTextNode を使う方が良いかもしれませんね… 最新コードの146、149、153、233、236、240行目を変更いたしました。 要素を空にするコードではないかと勘違いしていたようで、初めに dell_ok さんにわからないところをお聞きしたほうが良かったです。 ※以前アドバイス頂いたコード ※元のコード function lengthCheck() { const left = this.dataset.maxlength - this.value.length; if (left >= 0) { this.nextElementSibling.innerHTML = 'あと<strong>' + left + '</strong>文字'; this.dataset.submit_disabled = this.value.length === 0; } else { this.nextElementSibling.innerHTML = '<strong>' + -left + '</strong>文字超過しています'; this.dataset.submit_disabled = true; } ↓ ※エスケープ処理 function escapeHTML(値) { _ var a = document.createElement('span'); _ a.textContent = 値; _ return a.innerHTML; } 要素.innerHTML = '<strong>' + escapeHTML(文字列) + '</strong>'; ※最新コード https://wandbox.org/permlink/ozofFRK7rkjCXV76 ______________________________ 質問の期限が切れてしまったため下記リンクに質問を立てさせていただきました。よろしくお願い致します。 ※新規質問 https://okwave.jp/qa/q10207678.html