**[[質問箱4/129]] [#p18f3a9f]
#author("2018-03-11T19:44:24+09:00;2009-03-20T19:20:19+09:00","","")
**[[質問箱/4129]] [#p18f3a9f]
|RIGHT:70|LEFT:410|c
|~カテゴリ||
|~サマリ|#comment、 でIEの更新(再描画)ボタンを押すと二重投稿される|
|~バージョン|1.4.x|
|~投稿者|[[kahata]]|
|~状態|完了|
|~投稿日|&new{2007-07-03 (火) 10:44:00};|
***質問 [#r3185f2a]
拙作、[[自作プラグイン/include_module.inc.php]]の使い方を模索している[[kahata]]です。

プラグイン、#commentについて質問させていただきます。~
コメントを投稿(挿入)した直後に、インターネットエクスプローラ等の更新(再描画)ボタンを押すと、情報の再送信を警告するポップアップが出て、再送信を強行すると以下のメッセージが出て二重投稿されてます。

 練習ページ で【更新の衝突】が起きました
 あなたがこのページを編集している間に、他の人が同じページを更新してしまったようです。
 コメントを追加しましたが、違う位置に挿入されているかもしれません。

#articleでも同様の現象が起きますが、編集画面が出て二重投稿はされないようです。~
投稿のときのpostをそのまま再送信しているためこの現象が起きると思うのですが、この二重投稿を防止する方法はないでしょうか? #commentなら二重投稿を削除すれば済みますが、一般的な掲示板等のアプリケーションでpukiwikiのpost,getを使う場合、更新ボタンを押す度に多重投稿になっては困ります。~
色々コードをいじりましたが解決できません。~
以下のコードが関係していると思いますが、ifの条件文の中身がよく理解できません。

	$title = $_title_updated;
	$body = '';
	if (md5(@join('', get_source($vars['refer']))) != $vars['digest']) {
		$title = $_title_comment_collided;
		$body  = $_msg_comment_collided . make_pagelink($vars['refer']);
	}
 
	page_write($vars['refer'], $postdata);
このコードの意味も併せてご教授下さい。宜しくお願いします。



***回答 [#jbe33756]
-ちょうどこの辺りのソースを読んだところだったので、自分のまとめを兼ねて。間違っていたらご指摘下さい>詳しい方々 -- [[ぃぉぃぉ]] 2007-07-03 (火) 12:27:51
--	$title = $_title_updated;&br;
ページタイトル(標準スキンで一番上に表示されるやつ)を「~を更新しました」にする。
--	$body = '';&br;
エラーメッセージを空にする。(lib/pukiwiki.phpのretvarsにbody、msgがあると、エラー扱い)
--	if (md5(@join('', get_source($vars['refer']))) != $vars['digest']) {&br;
次の二つの比較。
---md5(join('', get_source($vars['refer'])))&br;
現在のページのmd5ハッシュ(チェックサムの様なもの)。この時点でファイルから計算。
---$vars['digest'])&br;元のページのチェックサム。commentプラグインのあるページが表示された時点で計算されている。
--		$title = $_title_comment_collided;&br;
タイトルを衝突検出に。
--		$body  = $_msg_comment_collided . make_pagelink($vars['refer']);&br;
本文を衝突検出に。
--	page_write($vars['refer'], $postdata);&br;
ページの更新。(wiki/以下のファイル更新)
- 衝突時はpage_writeをやめてごにょごにょする、ってのは手ですね。 -- [[ぃぉぃぉ]] &new{2007-07-03 (火) 12:31:44};
- 強制的に書き込んでいるのは、&br;ユーザーの行動
 (a)ページを開く
 (b)ページを読んでコメントを入力する
 (c)コメント挿入ボタンを押す
で、(b)の間に他にコメントが入ったりページが更新されても、プラグインは(c)でソース読み直すので、衝突はあってもコメントが書き込まれ、ユーザーの期待する動作になっているので良いでしょう。けれど、強制的に書き込まずに、差し戻す、もしくは確認画面を噛ませる、という案も受け入れられると思います。(書き込み後にページを更新して、同じコメントが追加されなくなる。) -- [[ぃぉぃぉ]] &new{2007-07-03 (火) 13:03:25};
-- 蛇足ですが、独立したアプリ(モジュール)の場合、人が編集中の時に他人が編集できないようロックしたりするのは、そのアプリの仕事でwikiの仕事ではありません。今ちょっと思い出したもので・・・ --[[kahata]] &new{2007-07-03 (火) 20:04:02};
- ありがとうございます。ということは、(日本語で言うと文字通り)postする人が最初にそのページを開いた時と、postした時点で(誰かが書き込んで)ページの内容が異なっていれば、collidedの警告を発しなさいということですね。このアルゴリズムによると何れにせよ(同じであっても異なっていても)post値が強制的にページに書き込まれます。~
仰るとおりページ内容が異なっていた場合writeを止めるのは#commentでは可能かもしれません。しかし一般掲示板ではpostデータをファイルに書き出すので検出が難しいです。端的に言えば同じposterがブラウザ更新ボタンを何回も押して同じpostデータを発信しているのを事前に検出したいのですが、このようなことは可能でしょうか。postの処理を行う前にsubmitのvalue値を''にしたりしてみましたがうまくいきません。 -- [[kahata]] &new{2007-07-03 (火) 12:49:02};
- postデータはブラウザ内に保存されているので難しいでしょうね...。って、そうか、書き込みシリアル番号を発行してpostデータに埋め込むとか...?&br;それよりも、[[dev:BugTrack2/239]]この案2はだめ? -- [[ぃぉぃぉ]] &new{2007-07-03 (火) 13:15:21};
-- [[dev:BugTrack2/239]]この案2みました。何となくですが?下記で言っているperl/cgiに近いような気がします。ヒントありがとうございます。--[[kahata]] &new{2007-07-03 (火) 13:59:02};
- ちょっとヒントになりそうなのは、perl/cgi等ではscriptを最初から読み直して初期化しているようですがよく判りません。ちなみにwikiでもコメント投稿後に一旦別ページを開いて、また#commentのページに戻ると、今度は何度更新ボタンを押しても多重書き込みは起こりませんが、、、 --[[kahata]] &new{2007-07-03 (火) 13:13:02};
-  ぃぉぃぉさんありがとうございました。 ''[[dev:BugTrack2/239]]早速試みてうまくいきました。'' ページを読み直しているわけですから、まさにcgi/一般phpで採られている方法で、この方法だと情報再送信の警告も出ません。これでpost/getを使った一般的アプリケーションをwiki上で実行できるようになりそうです。『なにもここまでしなくとも cgiのサイトを#iframeか外部リンクで引っ張ってくればよいじゃないか』との声が出そうですが、wiki応用の範囲が広がるだけでも意味があると思います。 -- [[kahata]] &new{2007-07-03 (火) 14:41:17};
- 一応解決しましたが、他にもアイデアがあるかも知れません。また他の方の参考になるかもしれませんので、私としてはしばらく質問のまま残しておきます。 -- [[kahata]] &new{2007-07-03 (火) 14:55:47};
- [[自作プラグイン/include_module.inc.php]]に同梱したサンプルのコメントモジュールを更新しました。 -- [[kahata]] &new{2007-07-03 (火) 16:38:46};
- 解決おめでとうございます。お役に立ってよかったです。&br;ステータスを「完了」にしておいても他の方の参考になりますので、解決したら完了にして頂きたいです。具体的な要望・疑問があるのであれば、「質問」のままで良いと思います。(その際はその内容も記載して下さいね。) -- [[ぃぉぃぉ]] &new{2007-07-03 (火) 18:02:53};
--- 了解しました。 ありがとうございました。-- [[kahata]] &new{2007-07-03 (火) 18:08:42};

//#comment

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Site admin: PukiWiki Development Team

PukiWiki 1.5.4+ © 2001-2022 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u12. HTML convert time: 0.043 sec.

OSDN