たまに実装すると、すっかり忘れていることを痛感するので、メモ。
以下では snippet src しか記載していませんが、詳細は察して下さい。
client側 ( jquery / javascript )
FormBase.prototype = { api_url: "/cgi-bin3/form.php", err_url: "/contact3/common/error.html", err_msg_elm: "#callback_error", // 入力→確認画面遷移に伴う入力確認 submit_input_to_confirm: function(){ $(this.err_msg_elm).empty(); form_data = this.collect_form_datas(); var this_obj = this; var request = $.ajax({ type: 'POST', url: this.api_url, data: form_data, dataType: 'jsonp', jsonpCallback: 'callback_input_to_confirm' }); request.done(function(data,text_status){ return this_obj.callback_input_to_confirm(data); }); request.fail(function(jqXHR, textStatus, errorThrown) { window.onbeforeunload = null; //「離れていいですか?」をOFF $(window).off('beforeunload'); window.location.href = this_obj.err_url; }); }, callback_input_to_confirm:function(submit_result){ // OK→ セッションNoを受領し、確認画面を表示 if(submit_result["result"]=="OK"){ this.session_id = submit_result["session_id"]; return this.init_confirm_page(); } this.session_id = ''; // NG→ 画面遷移せず、エラー内容を表示 if("errors" in submit_result ){ for (var atri_key in submit_result["errors"] ) { for (var i=0; i<submit_result["errors"][atri_key].length; i++){ var err_msg = submit_result["errors"][atri_key][i]; $(this.err_msg_elm).append('<li>'+ err_msg +'</li>'); } } $('html').animate( {scrollTop: $('.flow').offset().top - 50} ); } }, }
server側 ( php )
class HelmForm4Client extends HelmForm { const JSONP_RES_HEADER = 'Content-Type: text/javascript; charset=utf-8'; function __construct() { $this->ini_set(); } function main(){ $func_name = __CLASS__." ".__FUNCTION__; $refferer = $_SERVER['HTTP_REFERER']; $parsed_url = parse_url($refferer); $this->write_log("START $func_name from $refferer"); $assign_form_def = $this->assign_form_def($parsed_url['host'], $parsed_url['path']); // request元からのaccess可否判定 if( ! $assign_form_def ){ $this->write_log("ERROR not assigned foom: $refferer"); http_response_code( 500 ); header(self::JSONP_RES_HEADER); echo "({'result':'NG',sys_msg':'bad request'});"; return; } $callback_method = $_GET["callback"]; //入力画面→確認画面 遷移時 if(strcmp($callback_method,"callback_input_to_confirm")==0){ return $this->main_input_to_confirm($callback_method, $assign_form_def); } //確認画面→完了画面 遷移時 if(strcmp($callback_method,"callback_confirm_to_complete")==0){ $result_main = $this->main_confirm_to_complete($callback_method, $assign_form_def); return $result_main; } http_response_code( 500 ); $this->write_log("WARN unknown request ". $_SERVER['REQUEST_URI'] ); } //入力画面→確認画面 遷移時 function main_input_to_confirm($callback_method, $assign_form_def){ $func_name = __CLASS__." ".__FUNCTION__; $refferer = $assign_form_def['path']; // session id設定とsession開始 session_id(sha1(uniqid(microtime()))); if( session_start() ){ $session_id = session_id(); } $this->write_log("START $func_name session:$session_id $refferer"); // validation ruleのload $validation_def = $this->validation_def($assign_form_def['validation_rule']); // request parameterの取得とvalidation $params_defs = $validation_def["definition"]; // 住所、氏名等のpost reqesut parameterを取得 $req_params_tmp = $this->load_req_params($params_defs, $_POST); $req_params = $req_params_tmp[0]; $errors = $req_params_tmp[1]; // カタログに関する post reqesut parameterを取得 $catalog = new HelmForm4Catalog(); $max_catalogs = $assign_form_def["max_catalogs"]; $req_params_tmp = $catalog->load_req_params($_POST,$max_catalogs); $req_params = array_merge($req_params, $req_params_tmp[0]); $errors = array_merge($errors, $req_params_tmp[1]); $_SESSION['req_params'] = $req_params; //validationの結果、errorなしなら、session idをclientへ返します if( count($errors)==0 ){ $req_result_json = $this->json_encode(["result" =>"OK", "session_id"=>$session_id]); echo $callback_method ."(".$req_result_json .");"; $this->write_log("DONE $func_name session:$session_id"); return true; } $this->write_log("WARN fail validation $func_name session:$session_id"); $tmp_msg = "validation result:". print_r($errors,true); // $tmp_msg = str_replace ("\n"," ",$tmp_msg); $tmp_msg = preg_replace("/\s+/"," ",$tmp_msg); $this->write_log($tmp_msg); $req_result_json = $this->json_encode(["result"=>"NG","errors"=>$errors]); $callback_method_all = $callback_method ."(".$req_result_json .");"; header(self::JSONP_RES_HEADER); echo $callback_method_all; // セッション情報破棄 $_SESSION = []; session_destroy(); return false; } }