- ベストアンサー
テキストエリアでタグ使用可…
CGI勉強中です。 掲示板を作っているのですが、テキストエリア内でタグを使用できるようにするにはどうしたら良いのですか? ってここに解答を書いていただいたらそれはそれでうれしいのですが、 「このサイトに詳しく載っているよ」の方が、自分のためにもなると思うので、そういったサイトをご存知だったら教えてください。 よろしくお願いいたします。
- master-3rd
- お礼率39% (524/1325)
- CGI
- 回答数13
- ありがとう数15
- みんなの回答 (13)
- 専門家の回答
質問者が選んだベストアンサー
タグを許可する時は「全てのタグをエスケープし、許可するもののみ戻す」という方法をとります。 以下、入力文字列が $val に入っているものとします。 タグのエスケープでは、 $val =~ s/&/&/g; $val =~ s/</</g; $val =~ s/>/>/g; $val =~ s/"/"/g; を行います。( & の変換は最初に行うこと) 属性のないタグは $val =~ s/<(\/?b)>/<$1>/gi; という方法で元に戻します。 多くの掲示板でそうであるように、特殊な入力を強いる必要はありません。 (許可するタグの「閉じタグ」もこの方法で戻します。) 属性のあるタグは、タグを解析します。 正規表現で許可するタグを拾い、それぞれのタグ解析ルーチンから正常な属性文字列を取得してタグを戻します。 # ↓ここに許可するタグを書く while ($val =~ /<(font|img)\s+(.*?)>/gi) { my $tgt = quotemeta $&; # 拾ったタグ全体 my ($tag, $attr) = ($1, $2); $attr =~ s/"/"/; # 属性部をアンエスケープ $attr =~ s/&/&/; my @attrs = split /\s+/, $attr; # 属性を分解 # それぞれのタグ解析ルーチンへ if ($1 =~ /font/i) { $tag .= tag_font(@attrs); } elsif ($1 =~ /img/i) { $tag .= tag_img(@attrs); } # タグを戻す $val =~ s/$tgt/<$tag>/; } 例えば font タグ用の解析ルーチン tag_font は、次のようになります。 sub tag_font { my $tag; foreach (@_) { my ($attr, $val) = split /=/; $val =~ tr/"'//d; # 許可する属性のみ $tag に追加する if (lc($attr) eq 'size') { # ±1~3 または 1~7 を許可 if ($val =~ /^[+-][1-3]|[1-7]$/) { $tag .= qq{ $attr="$val"}; } } elsif (lc($attr) eq 'color') { if ($val =~ /^#[A-Fa-f0-9]{6}|[A-Za-z]+$/) { $tag .= qq{ $attr="$val"}; } } } return $tag; } また、URLやメールアドレスの自動リンクについては、「Perlメモ(参考URL)」というサイトの「http URL の正規表現」や「メールアドレスの正規表現」の項にある正規表現が大変便利です。 各項の一番最後に書かれている $http_URL_regex と $mail_regex を使い、次のように書くことができます。 ・メールアドレスの自動リンク $val =~ s/($mail_regex)/<a href="mailto:$1">$1<\/a>/g; ・URLの自動リンク URLの自動リンクには注意が必要です。 なぜなら $http_URL_regex が、imgタグのsrc属性値までも対象としてしまうからです。 これを回避するためには、次のように書きます。 while ($val =~ /($http_URL_regex)/g) { my $url = $1; # マッチした URL の後続文字列 $' の先頭を調べ、 # img の src や変換済み URL を変換しないようにする if ($' !~ /^"|<\/a>/) { $val =~ s/$url/<a href="$url">$url<\/a>/; } } 以上を組み合わせれば、タグの許可および自動リンクが実現できます。
その他の回答 (12)
- Marionette
- ベストアンサー率56% (42/74)
> 多くの掲示板でそうであるように、特殊な入力を強いる必要はありません。 どちらも一長一短ありますね。 (タグを多用することがあるかどうかは)掲示板のテーマしだいですが、タグ(の書き方)を記述するのに、「<div>」、「<b>」等と使い分けなきゃいけないのもどうかと思いますけど。すべて文字参照、というのはもっといやですね。 特殊な入力とはいっても、工夫さえすれば問題ないと思いますよ。 これも、#6で紹介したphpBBで採られていた方法をいただいたのですが、マウスクリックまたはメタキーでサイクリックに入力できるので、直接書くよりは楽です。 あとは、質問者さんの好みで決めればいいのではないでしょうか。
- Marionette
- ベストアンサー率56% (42/74)
またまたすみませんです。補足を意味を取り違えておりました。 > <a hreh>はhttpで始まるものは自動でリンクに変換(よく見かけますよね)のほうが良いのでは?この方法はどうしたらいいでしょうか? いいかどうかはポリシー、ページのテーマにもよると思います。 例えばここですが、解説のために例示した架空のURLがリンクになっては困りますよね。 個人的には明示的に入力する方を選びます。 やり方は #6,#10および#10のURLを参考にガンバッテください。
お礼
ありがとうございます。 とりあえずがんばってみます。
- Marionette
- ベストアンサー率56% (42/74)
> <a hreh>はhttpで始まるものは自動でリンクに変換(よく見かけますよね)のほうが良いのでは?この方法はどうしたらいいでしょうか? > あとの問題は、<font>と<img>。<>内に語句が入るため> |**|では対応できないですよね。何か良い方法無いでしょうか? #6に回答が書いてありますよ? あれを、perlに書き換えるだけです。perlの場合、「/」をエスケープする必要があるかも分かりません。 <a href=\"\\1\" target=\"_brank\">\\1</a> の\\1が、正規表現に一致した内容、つまり、|url|,|/ulr|ではさまれたURLになります。 \\1の数字の部分が、「(」の出現順の番号です。\\2なら、httpかftpですね。 > htm(l)で終わる分は<a href></a>に変え[HOME]等を表示 気休めですが、[HOME]のような表示はやめて、URLをそのまま表示した方が、良いかと思います。 <img>は#6の正規表現をアレンジして最後に 「\.(gif|jpg|jpeg|png|)」を追加すればいいかな。 正規表現については、参考URLの「perl」に詳しい解説が有ります。
- Marionette
- ベストアンサー率56% (42/74)
補足です。 タグですが、入力を簡単にするため、許可したタグのボタンを全部ならべて、クリックでテキストエリアに入力するJavaScriptを組んであります。これなら、何が使用可能か一目瞭然です。 ところで、画像は具体的にどうしたいのでしょうね? 自由度が増すほど登録メンバーのみ投稿を許可などの制限を設けた方が良いと思います。 phpBBという高機能な掲示板がありまして、サーバ側で用意して選択させる方法、サイズを制限してアップロード可能な方法、画像へのリンク、いずれも出来るようになっており参考になりました。もちろんメンバー制です。 ソースはかなり複雑です。 #6のサンプルは、英数字、チルダ、ハイフン、スラッシュ、ドット以外の文字が含まれていたら変換しないようになってます。 (イメージは拡張子 gif, jpg, pngのみ許可。) > ただ、<A>や<IMG>許可するようであれば、 > タグ全て許可と対して変わらないかもしれませんよ。 表示の問題もあるのでなるべく制限した方がいいでしょう。<table>など下手に使われると目茶苦茶になりますしね。
- the845t
- ベストアンサー率33% (246/743)
たぶん、皆さんの発言で解決は出来ると思いますが、 質問するのでしたら、テキストエリア内でタグを利用できるように・・・ ではなく、 掲示板の投稿時、タグを反映させたいのですが・・・ でしたね。 タグの全て許可はたしかに危険ですが、 JavaScriptと、スタイルシートの許可さえしなければ、 いうほど危険もないかもしれません。 ただ、<A>や<IMG>許可するようであれば、 タグ全て許可と対して変わらないかもしれませんよ。 conconなんてのがあるし、<A>内にJavaScriptでなんでもありになりますから。 文字装飾だけの許可にしては? URLのリンクは、#4さんがおっしゃるような形か、 URL部分を抜いておいて( 参照リンク )と言った形でリンクするとかね。 最後に、タグ閉じ忘れのケアレスミスにご注意を。
補足
回答ありがとうございます。 なにぶん初心者なので、どう説明したら良いのかがわからず、変な書き方しちゃいました。すみませんでした。 さて、問題の件ですが、リンクは#7でも書きましたが、自動変換で対応できないかと考えました。これでもダメですか? <img>はやっぱり必要なんです。どうにかならないですかね… … …… でも、よく考えると、<img>使用するんだったら画像アップローダーが必要ですよね。 ただの画像表示(リンクのみ)だったらさっきの自動リンクで何とかならないですかね。 htm(l)で終わる分は<a href></a>に変え[HOME]等を表示、gif・jp(e)gは<img>に変換… こんな都合いい事出来ないですか?
- Marionette
- ベストアンサー率56% (42/74)
#6 です。すいません、また、違ってました。 ポストしたあと見たら書いたほど、厳密なチェックではありませんね。 やろうとしたのですが、 http://xxxx.yyy.zz/~abc/ddd.eee/index.html なんてのまで考えると複雑になりすぎるので断念したのでした。
補足
いろいろとありがとうございます。 いろいろと弊害があるということがわかってきたので、ちょっとやり方を変えたいと思います。 <B>は「$value =~ s/|b|/<b>/g; 」で対応するとします。 <a hreh>はhttpで始まるものは自動でリンクに変換(よく見かけますよね)のほうが良いのでは?この方法はどうしたらいいでしょうか? あとの問題は、<font>と<img>。<>内に語句が入るため|**|では対応できないですよね。何か良い方法無いでしょうか?
- Marionette
- ベストアンサー率56% (42/74)
> $value =~ s/</</g; > $value =~ s/>/>/g; > $value =~ s/|b|/<b>/g; > であってますか? それで OKです。 ついでに、URLのやり方ですが、|url|http://~|/url|の形で入力して $str = ereg_replace("|url|((http|ftp)://(([0-9a-zA-Z\-~_]+)\.)+([0-9a-zA-Z\-~_]+)([0-9a-zA-Z\-~_\./]*))|/url|","<a href=\"\\1\" target=\"_brank\">\\1</a>",$str); とやってます。 PHPなので、perlとは違いますが、正規表現は使えるのではないでしょうか。 上記の正規表現は、URLの記述の正しさのチェックもおこなっています。 ○ http://xxxx.yyyy.zzz × http://xxx.yyy.zzz. × http://xxx.yyy という結果になるはずです。 # もっと簡単に書けるかもわかりませんが、//以下が必ず三つ以上のパートから構成されていて最後が2文字以上の英字でないとNG(変換されずにそのまま表示される)になるように厳密にチェックしています(..のつもりなんですが)。 いい加減に評価するならもっと簡単になります。
- Marionette
- ベストアンサー率56% (42/74)
#4です。一箇所間違えました。 >修正機能をもたせる場合、<は&lt;と変換してテキストエリアに表示しないとタグが有効になってしまいます。 「<を&lt;と変換しないと、< と表示されず < になる」に訂正します。
- Marionette
- ベストアンサー率56% (42/74)
最近、限定タグのみ使用可能にした掲示板を完成させたばかりなので。 「テキストエリア」とは #1に書いてある通り、掲示板等で入力するためのエリア(質問をポストした時のあの入力するための領域のことです)なのでタグの効果は反映されません。 スタイルシートで色や文字の大きさを指定したりする程度のことが出来るのは#2の通りです。 で、私の場合、 1.<, >を<, >に変換してタグを無効化。 2.特別に決めた表現のみHTMLタグに変換。例えば、|b|等と表現した場合に<b>に変換。 というふうにやりました。 但し、URLなど、値が変わる場合、正規表現を使う必要がありますし、入力された文字の正当性を評価することも必要だと思います(URLが複数指定された場合を考慮すると、かなり複雑な正規表現になります)。 修正機能をもたせる場合、<は&lt;と変換してテキストエリアに表示しないとタグが有効になってしまいます。 全てのタグを許可するなら、なにもしなくてもOKですが、やめといた方が無難だと思います。
お礼
ありがとうございます。そのことが知りたかったんです。 sub Decode内に「$value =~ s/</</g;」と「$value =~ s/>/>/g;」があったためコメントアウト「先頭に#」してタグが有効になるようにしました。 ただ、言われるとおりこのままだとすべてのタグが使用できてしまうんですよね。 <a href><B><font><img>のみ使用可能というCGIを見かけましたが、どうやっているのですか?DLして中を見てみたのですが、いまいちよくわからずです。 ちなみに、 >例えば、|b|等と表現した場合に<b>に変換。 は、 $value =~ s/</</g; $value =~ s/>/>/g; $value =~ s/|b|/<b>/g; であってますか?
あまり詳しくない上、具体的なコードも提示できないのですが、概要は下記の要領です。 (1) 入力された文字列をパターンマッチングで照合し、「特殊な文字」(参考URL)を最初にすべて無効化(コメントアウト)する。 (2) 上記で無効化した箇所のうち、使用を許可するタグに一致する部分のみをピックアップしてコメントをはずす。 ざっとこんな感じだったと思います。 以前に、Perlで書かれた掲示板CGIのソースで上記の趣旨の処理を見た記憶があります。 BBSでのタグの使用はトラブルの原因ともなり得るため、慎重に!
お礼
ありがとうございます。 とりあえず勉強してみます。
- 1
- 2
関連するQ&A
- Javascriptでテキストエリアにタグの制限をかけたいです。
フォームで、テキストエリアの作成をしましたが、 迷惑メールで、テキストエリアにタグを入れて来るようになってしまったのですが、 テキストエリアへ、タグが入らないようにする、javascriptとかはありますでしょうか? あれば教えて下さい。
- ベストアンサー
- JavaScript
- タグ使用可の、掲示板スクリプトを探してます!(フリーで)
こんにちわm(__)m 掲示板のスクリプトを落としたいのですが、 今のところ見つけたのはどれもタグが使用不可のものでした。 どんなものでもいいので、タグの使用が可能な、掲示板のCGI(できればperl) スクリプトを落とせるところを教えてください! お願いしますm(__)m
- ベストアンサー
- Perl
- 複数行テキストエリアについて
複数行テキストエリアのデータを CGIで文字数・エラー文字などをチェックし、 その結果によって、テキストエリアを編集可能にしたり、編集不可能にしたりしたいのですが、その方法がイマイチ分かりません。 cgiはperlで作っており、 $txt 加工したテキストデータ $flg 判定フラグ(0:OK 0以外:NG) として if($flg != 0){ 加工したテキストを表示し、編集可能状態のテキストエリアのHTMLタグ }else{ 加工したテキストを表示し、編集不可能状態のテキストエリアのHTMLタグ } というようにしたいのですが、どのようにテキストエリアに加工したテキストデータを渡せばよいのかが分からず困っています。 すみませんが教えて下さい。
- ベストアンサー
- Perl
- テキストエリアについて
HPのトップページに日記を載せるために、テキストエリアを設置したのですが、テキストエリア内ではタグって使えないんですか? 色を変えたり文字の大きさを変えたりしたいのですが、何かいい方法はないでしょうか? よろしくお願いします!
- ベストアンサー
- その他(インターネット・Webサービス)
- 自分のホームページにフォームのテキストエリアを入れてみたいのですが...?
自分のホームページにフォームのテキストエリアを入れてみたいのですが、CGIの知識は必要なのですしょうか? 本を買って、CGIの勉強をしようと思っているのですが、私は、自分のホームページに、「いつでも、何処でも(インターネットがつかえる所なら)記入できる」メモ帳というか、日記帳みたいなものを作りたいのですが、CGIを一通り勉強しないと使えないものなんでしょうか?
- ベストアンサー
- CSS
- 日記でIMGタグを使用可にしたいのです。
自分のHPで独り言と称して日記を公開しています。 以前は、毎回HTMLファイルを作成していたのですが、今はCGIを頂いてきて使っています。 そのCGIでは、タグの使用を制限しており、プログラム文中には、改造も可能と書いてあるのですが、どこを変えればよいのか、自分なりに調べたのですが分かりません。 属性に問題があるのかとも思いますが、初心者に毛が生えた程度の知識なもので、理解が出来ていません。 どこを変更すればよいか、お分かりになる方がいらっしゃいましたら、よろしくお願いします。 CGIは、以下のサイトからいただいてきました。 http://wa-ka.net/mash/sozai/ariake/index.html
- 締切済み
- CGI
- テキストエリアについての質問です。
携帯サイトでテキストエリアを使っています。 <a href=゛゛></a>のタグをテキストエリア内に書いたところ、パソコンだと普通に表示されるのですが、携帯だと゛゛の間に変な英語と数字が沢山表示されます。 携帯でも普通に表示するには、どうすればいいのか分かりません。 教えてください。 よろしくお願いします。 テキストエリアはこのように書いています。 <form action゛.゛><textarea cols=゛8゛ rows=゛1゛> <a href=゛゛></a> </textarea></form>
- ベストアンサー
- HTML
- JavaScript~フォームのテキストエリアの設定
フォームのテキストエリアの背景色を指定できたと思うのですが、 どのサイトでそれを見たのか忘れてしまい、どうしても見つかりません(^-^;; 方法、又は説明のあるサイトをご存知でしたら教えて下さい。 あと、同じくフォームのテキストエリアで、 入力した文字のフォントの種類やサイズを指定できますか? 読み込んだあとではなくて、書いているときです。 (説明が下手でごめんなさい) ネスケで見たときにテキストエリアが広くなってしまって、 掲示板等のデザインが崩れてしまいます。 同じ数値で指定するとI.E.よりネスケのほうが広くなるし字も大きいのですが、 ネスケ用に別指定等できるのでしょうか? お時間のあるときで構いませんので宜しくお願いします。
- ベストアンサー
- JavaScript
- テキストエリアの改行を取得したい
最近CGIを独学ではじめたのですが、複数行のテキストエリアからの文字列の取得をした場合、改行が反映されずに表示されます。 改行コードのようなものは取得されている、とちらりとどこかで見たことがあるのですが、どのように取得して改行させるかが分かりません。 すみませんが、ご存知の方がいらっしゃいましたら教えていただけないでしょうか。 このような感じで書きました。 my $cgi = CGI::new(); my $area = $cgi->param('text'); print "Content-type: text/html\n\n"; print $area;
- ベストアンサー
- CGI
お礼
詳しい説明ありがとうございます。 何とかなりそうです。 ホントCGIって難しいですね。まだまだ勉強が必要です。