たまに実装すると、すっかり忘れていることを痛感するので、メモ。
以下では 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;
}
}