二重送信制御

本文详细介绍了二重送信禁止JavaScript技术的核心内容、使用方法及注意事项,包括如何开始控制、设置允许条件、处理二重送信错误和上传错误等关键步骤。
/*
* COPYRIGHT (C) 2010 NEC CORPORATION
*
* ALL RIGHTS RESERVED BY NEC CORPORATION, THIS PROGRAM
* MUST BE USED SOLELY FOR THE PURPOSE FOR WHICH IT WAS
* FURNISHED BY NEC CORPORATION, NO PART OF THIS PROGRAM
* MAY BE REPRODUCED OR DISCLOSED TO OTHERS, IN ANY FORM
* WITHOUT THE PRIOR WRITTEN PERMISSION OF NEC CORPORATION.
*
* NEC CONFIDENTIAL AND PROPRIETARY
*/

/**
* @fileOverview
* 二重送信禁止 JavaScript 部品です.
*/

var sde = sde || {};

/**
* @namespace
* <p>二重送信禁止 JavaScript 部品です.
* 送信ボタンのダブルクリックなどによる二重送信を禁止します。</p>
*
* <p>sde.doubleSubmission.start メソッドを呼び出すと制御を開始します。
* ただし、HTML 中の要素が作成された後に呼び出す必要があります。
* このため、通常は以下のように jQuery.ready または jQuery.load
* で登録します。</p>
*
* <pre>
* jQuery(document).ready(sde.doubleSubmission.start);
* または
* jQuery(window).load(sde.doubleSubmission.start);
* </pre>
*
* <p>load イベント処理中に送信を行うような場合は、
* それより前に sde.doubleSubmission.start メソッドを
* 実行しておく必要があります。</p>
*
* <p>JavaScript で動的に form 要素を追加した場合は、
* sde.doubleSubmission.start メソッドを再度呼び出す必要があります。
* また、IE でアップロード用(enctype属性が"multipart/form-data")の
* フォーム配下に submit ボタンを動的に追加した場合も
* 同様に再度呼び出す必要があります。</p>
*
* <p>form 要素の class 属性に
* "sde_doubleSubmission_allowed" が含まれていれば
* 二重送信を許可します。</p>
*
* <p>また、sde.doubleSubmission.setAllowed(true) と設定した場合も
* 二重送信を許可します。</p>
*/
sde.doubleSubmission = {};

/**
* 二重送信を許可するなら true、禁止するなら false
* (デフォルトは false).
*
* @private
*/
sde.doubleSubmission.allowed = false;

/**
* 次回の送信を許可するなら true、禁止するなら false
* (デフォルトは false).
*
* @private
*/
sde.doubleSubmission.nextSubmissionAllowed = false;

/**
* 送信中なら true、そうでなければ false
*
* @private
*/
sde.doubleSubmission.blocked = false;

/**
* ブロック処理関数(未送信から送信中に変更した場合に呼び出す関数)
*
* @private
*/
sde.doubleSubmission.blockFunction = null;

/**
* ブロック解除処理関数(送信中から未送信に変更した場合に呼び出す関数)
*
* @private
*/
sde.doubleSubmission.unblockFunction = null;

/**
* 二重送信エラー処理関数
* (送信ボタンのダブルクリック等、送信中に送信しようした場合に呼び出す関数)
*
* @private
*/
sde.doubleSubmission.doubleSubmissionErrorFunction = null;

/**
* アップロードエラー処理関数
* (アップロードするファイル名が相対パスやスペース等の間違ったファイル名で
* アップロードに失敗した場合に呼び出す関数)
*
* @private
*/
sde.doubleSubmission.uploadErrorFunction = null;

/**
* onsubmit イベントの fireEvent 実行中なら true、そうでなければ false
*
* @private
*/
sde.doubleSubmission.onsubmitEventFiring = false;

/**
* 二重送信を許可するなら true、禁止するなら false
* (デフォルトは false) を返します.
*
* @return 二重送信を許可するなら true、
* 禁止するなら false
*/
sde.doubleSubmission.isAllowed = function () {
return sde.doubleSubmission.allowed;
};

/**
* 二重送信を許可するなら true、禁止するなら false
* (デフォルトは false) を設定します.
*
* @param value 二重送信を許可するなら true、
* 禁止するなら false
*/
sde.doubleSubmission.setAllowed = function (value) {
sde.doubleSubmission.allowed = value;
};

/**
* 次回の送信を許可するなら true、禁止するなら false
* (デフォルトは false) を返します.
*
* @return 次回の送信を許可するなら true、
* 禁止するなら false
*/
sde.doubleSubmission.isNextSubmissionAllowed = function () {
return sde.doubleSubmission.nextSubmissionAllowed;
};

/**
* <p>次回の送信を許可するなら true、禁止するなら false
* (デフォルトは false) を設定します.</p>
*
* <p>true に設定すると、次回の送信1回だけに限って、
* 二重送信であっても送信を許可し、その後この値は false に戻ります。
* また、その際に送信中かどうかの値(isBlockedが返す値)
* は変更しません。</p>
*
* @param value 次回の送信を許可するなら true、
* 禁止するなら false
*/
sde.doubleSubmission.setNextSubmissionAllowed = function (value) {
sde.doubleSubmission.nextSubmissionAllowed = value;
};

/**
* 送信中なら true、そうでなければ false
* を返します.
*
* @return 送信中なら true、そうでなければ false
*/
sde.doubleSubmission.isBlocked = function () {
return sde.doubleSubmission.blocked;
};

/**
* 送信中なら true、そうでなければ false
* を設定します.
*
* @param value 送信中なら true、そうでなければ false
*/
sde.doubleSubmission.setBlocked = function (value) {
if (sde.doubleSubmission.blocked === value) {
// 値の変更がない場合は何もしない
return;
}

sde.doubleSubmission.blocked = value;

if (sde.doubleSubmission.blocked) {
if (sde.doubleSubmission.blockFunction) {
sde.doubleSubmission.blockFunction();
}
} else {
if (sde.doubleSubmission.unblockFunction) {
sde.doubleSubmission.unblockFunction();
}
}
};

/**
* ブロック処理関数(未送信から送信中に変更した場合に呼び出す関数)
* を返します.
*
* @return ブロック処理関数。null なら呼び出さない。初期値は null
*/
sde.doubleSubmission.getBlockFunction = function () {
return sde.doubleSubmission.blockFunction;
};

/**
* ブロック処理関数(未送信から送信中に変更した場合に呼び出す関数)
* を設定します.
*
* @param value ブロック処理関数。null なら呼び出さない。初期値は null
*/
sde.doubleSubmission.setBlockFunction = function (value) {
sde.doubleSubmission.blockFunction = value;
};

/**
* ブロック解除処理関数(送信中から未送信に変更した場合に呼び出す関数)
* を返します.
*
* @return ブロック解除処理関数。null なら呼び出さない。初期値は null
*/
sde.doubleSubmission.getUnblockFunction = function () {
return sde.doubleSubmission.unblockFunction;
};

/**
* ブロック解除処理関数(送信中から未送信に変更した場合に呼び出す関数)
* を設定します.
*
* @param value ブロック解除処理関数。null なら呼び出さない。初期値は null
*/
sde.doubleSubmission.setUnblockFunction = function (value) {
sde.doubleSubmission.unblockFunction = value;
};

/**
* 二重送信エラー処理関数
* (送信ボタンのダブルクリック等、送信中に送信しようした場合に呼び出す関数)
* を返します.
*
* @return 二重送信エラー処理関数。null なら呼び出さない。初期値は null
*/
sde.doubleSubmission.getDoubleSubmissionErrorFunction = function () {
return sde.doubleSubmission.doubleSubmissionErrorFunction;
};

/**
* 二重送信エラー処理関数
* (送信ボタンのダブルクリック等、送信中に送信しようした場合に呼び出す関数)
* を設定します.
*
* @param value 二重送信エラー処理関数。null なら呼び出さない。初期値は null
*/
sde.doubleSubmission.setDoubleSubmissionErrorFunction = function (value) {
sde.doubleSubmission.doubleSubmissionErrorFunction = value;
};

/**
* アップロードエラー処理関数
* (アップロードするファイル名が相対パスやスペース等の間違ったファイル名で
* アップロードに失敗した場合に呼び出す関数)
* を返します.
*
* @return アップロードエラー処理関数。null なら呼び出さない。初期値は null
*/
sde.doubleSubmission.getUploadErrorFunction = function () {
return sde.doubleSubmission.uploadErrorFunction;
};

/**
* アップロードエラー処理関数
* (アップロードするファイル名が相対パスやスペース等の間違ったファイル名で
* アップロードに失敗した場合に呼び出す関数)
* を設定します.
*
* @param value アップロードエラー処理関数。
* null なら呼び出さない。初期値は null
*/
sde.doubleSubmission.setUploadErrorFunction = function (value) {
sde.doubleSubmission.uploadErrorFunction = value;
};

/**
* 二重送信禁止の制御を開始します.
* HTML 中の要素が作成された後に呼び出す必要があります。
*/
sde.doubleSubmission.start = function () {

for (var i = 0; i < document.forms.length; i++) {
var form = document.forms[i];

// フォームをカスタマイズ
sde.doubleSubmission.customizeForm(form);

if (sde.doubleSubmission.needsUploadErrorHandling(form)) {
// IEでアップロードを行うフォームの場合

// フォーム配下の全 submit ボタンをカスタマイズ
for (var j = 0; j < form.elements.length; j++) {
var control = form.elements[j];

if (control.tagName.toLowerCase() === 'input' &&
control.type === 'submit') {
// submit ボタンの場合
// submit ボタンをカスタマイズ
sde.doubleSubmission.customizeSubmitButton(control);
}
}
}
}

};

/**
* <p>指定のフォームをカスタマイズします.</p>
*
* @private
* @param form フォーム
*/
sde.doubleSubmission.customizeForm = function (form) {
if (form.sde_doubleSubmission_customized) {
// すでにカスタマイズ済みなら何もしない
return;
}
form.sde_doubleSubmission_customized = true;

// onsubmit のカスタマイズ
if (form.onsubmit) {
form.sde_doubleSubmission_onsubmit_original = form.onsubmit;
}
/** @ignore */
form.onsubmit = function () {
return sde.doubleSubmission.handleOnsubmit(this);
};

// submit メソッドのカスタマイズ
form.sde_doubleSubmission_submit_original = form.submit;
/** @ignore */
form.submit = function () {
sde.doubleSubmission.handleSubmit(this);
};

if (jQuery.browser.msie) {
// IEの場合
// fireEvent メソッドのカスタマイズ
form.sde_doubleSubmission_fireEvent_original = form.fireEvent;
/** @ignore */
form.fireEvent = function (sEvent, oEvent) {
return sde.doubleSubmission.handleFireEvent(
this, sEvent, oEvent);
};
}
};

/**
* <p>フォームの onsubmit のタイミングでの処理を行います。</p>
*
* @private
* @param form フォーム
* @return 送信を許可するなら true、禁止するなら false
*/
sde.doubleSubmission.handleOnsubmit = function (form) {
if (form.sde_doubleSubmission_onsubmit_original) {
try {
var ret = form.sde_doubleSubmission_onsubmit_original();
if (ret === false) {
// 本来の onsubmit で false を返した場合は送信しない
return false;
}
} catch (e) {
// onsubmit で例外発生しても以下の処理を行う
}
}

if (sde.doubleSubmission.onsubmitEventFiring) {
// onsubmit イベントの fireEvent 実行中なら送信中フラグは変更しない

// 送信を許可
return true;
}

if (sde.doubleSubmission.isAllowedForm(form)) {
// 二重送信を許可している場合

// 送信を許可
return true;

} else {
// 二重送信を禁止している場合

if (sde.doubleSubmission.isBlocked()) {
// 送信中の場合

// 二重送信エラー処理
sde.doubleSubmission.handleDoubleSubmissionError();

// 送信を禁止
return false;

} else {
// 未送信の場合

// 送信中に変更
sde.doubleSubmission.setBlocked(true);

// 送信を許可
return true;

}
}
};

/**
* <p>フォームの submit メソッドのタイミングでの処理を行います。</p>
*
* @private
* @param form フォーム
*/
sde.doubleSubmission.handleSubmit = function (form) {

if (sde.doubleSubmission.isAllowedForm(form)) {
// 二重送信を許可している場合

try {
// 本来の submit メソッドを呼び出す。
form.sde_doubleSubmission_submit_original();
} catch (e1) {
if (sde.doubleSubmission.needsUploadErrorHandling(form)) {
// アップロードエラー処理
sde.doubleSubmission.handleUploadError();
} else {
throw e1;
}
}

} else {
// 二重送信を禁止している場合

if (sde.doubleSubmission.isBlocked()) {
// 送信中の場合

// 二重送信エラー処理
sde.doubleSubmission.handleDoubleSubmissionError();

} else {
// 未送信の場合

// 送信中に変更
sde.doubleSubmission.setBlocked(true);

try {
// 本来の submit メソッドを呼び出す。
form.sde_doubleSubmission_submit_original();
} catch (e2) {
// 未送信に戻す
sde.doubleSubmission.setBlocked(false);

if (sde.doubleSubmission.needsUploadErrorHandling(form)) {
// アップロードエラー処理
sde.doubleSubmission.handleUploadError();
} else {
throw e2;
}
}

}
}
};

/**
* アップロードエラー時の処理が必要なフォームかどうかを返します.
*
* @private
* @param form フォーム
* @return アップロードエラー時の処理なら true、そうでなければ false
*/
sde.doubleSubmission.needsUploadErrorHandling = function (form) {
return jQuery.browser.msie && form.enctype === "multipart/form-data";
};

/**
* 二重送信を許可しているかどうかを返します.
*
* @private
* @param form フォーム
* @return 二重送信を許可しているなら true、そうでなければ false
*/
sde.doubleSubmission.isAllowedForm = function (form) {
if (sde.doubleSubmission.nextSubmissionAllowed) {
sde.doubleSubmission.nextSubmissionAllowed = false;
return true;
}
return sde.doubleSubmission.allowed ||
jQuery(form).hasClass("sde_doubleSubmission_allowed");
};

/**
* <p>フォームの fireEvent メソッドのタイミングでの処理を行います。</p>
*
* <p>IE で fireEvent メソッドを使用して
* onsubmit イベントが発生させられた場合、
* 送信は行われず、イベントだけが発生します。</p>
*
* <p>このため、onsubmit イベントの fireEvent メソッド実行中は、
* 送信中フラグを変更しないようにします。</p>
*
* <p>そうしないと、fireEvent() メソッドでイベント発生させた後に
* submit() メソッドで送信を行おうとした場合に
* 二重送信とみなされてしまいます。</p>
*
* @private
* @param form フォーム
* @param sEvent イベント名
* @param oEvent イベントオブジェクト
* @return fireEvent メソッドの戻り値
*/
sde.doubleSubmission.handleFireEvent = function (form, sEvent, oEvent) {
if (sEvent && sEvent.toLowerCase() === 'onsubmit') {
// onsubmit イベントの場合

var state = sde.doubleSubmission.onsubmitEventFiring;

// onsubmit イベントの fireEvent 実行中フラグを on
sde.doubleSubmission.onsubmitEventFiring = true;

// 本来の fireEvent メソッドを呼び出す
var result = form.sde_doubleSubmission_fireEvent_original(
sEvent, oEvent);

// onsubmit イベントの fireEvent 実行中フラグを元に戻す
sde.doubleSubmission.onsubmitEventFiring = state;

return result;

} else {
// それ以外のイベントの場合

// 本来の fireEvent メソッドを呼び出す
return form.sde_doubleSubmission_fireEvent_original(
sEvent, oEvent);

}
};

/**
* <p>指定の submit ボタンをカスタマイズします.</p>
*
* <p>IE でアップロードを行うフォーム用の処理です。</p>
*
* @private
* @param submitButton submit ボタン
*/
sde.doubleSubmission.customizeSubmitButton = function (submitButton) {
if (submitButton.sde_doubleSubmission_customized) {
// すでにカスタマイズ済みなら何もしない
return;
}
submitButton.sde_doubleSubmission_customized = true;

if (submitButton.onclick) {
submitButton.sde_doubleSubmission_onclick_original =
submitButton.onclick;
}
/** @ignore */
submitButton.onclick = function () {
sde.doubleSubmission.handleOnclickOfSubmitButton(this);
return false;
};
};

/**
* <p>submit ボタンの onclick のタイミングでの処理を行います。</p>
*
* <p>IE でアップロードを行うフォーム用の処理です。</p>
*
* <p>IEでは
* アップロードするファイルのパスが相対パスなどの場合に、
* 送信時にエラーとなって送信されません。</p>
*
* <p>この場合には送信中フラグを false に戻さないと
* 再送信できなくなるので、
* 送信中フラグを false に戻すようにしています。</p>
*
* <p>けれど、単に submit ボタンのクリックで送信した場合には
* エラー発生を把握できません。
* このため、submit ボタンの click イベント処理で
* 同じ name, value 属性の非表示の submit ボタンを作成し、
* その submit ボタンの click メソッドを呼び出して、
* 例外を catch します。</p>
*
* @private
* @param submitButton submit ボタン
*/
sde.doubleSubmission.handleOnclickOfSubmitButton = function (submitButton) {

if (submitButton.sde_doubleSubmission_onclick_original) {
try {
var ret = submitButton.sde_doubleSubmission_onclick_original();
if (ret === false) {
// 本来の onclick で false を返した場合は送信しない
return;
}
} catch (e) {
// onclick で例外発生しても以下の処理を行う
}
}

// 指定submitボタンと同じname,valueの非表示submitボタンを作成
var hiddenSubmit = document.createElement("input");
hiddenSubmit.type = "submit";
hiddenSubmit.name = submitButton.name;
hiddenSubmit.value = submitButton.value;
hiddenSubmit.style.display = 'none';

// 非表示submitボタンをフォームの子に追加
submitButton.form.appendChild(hiddenSubmit);

// 送信中フラグの現在の状態を取得
var state = sde.doubleSubmission.isBlocked();

var failed = false;
try {
// 非表示submitボタンをクリック
hiddenSubmit.click();
} catch (e2) {
failed = true;
}

// 非表示submitボタンをフォームの子から削除
submitButton.form.removeChild(hiddenSubmit);

if (failed) {
// 非表示submitボタンのクリックで例外が発生した場合

// 送信中フラグを元の状態に戻す
sde.doubleSubmission.setBlocked(state);

// アップロードエラー処理
sde.doubleSubmission.handleUploadError();
}

};

/**
* 二重送信エラー処理を行います。
*
* @private
*/
sde.doubleSubmission.handleDoubleSubmissionError = function () {

if (sde.doubleSubmission.doubleSubmissionErrorFunction) {
// 関数登録されていれば呼び出す
sde.doubleSubmission.doubleSubmissionErrorFunction();
}

};

/**
* アップロードエラー処理を行います。
*
* @private
*/
sde.doubleSubmission.handleUploadError = function () {

if (sde.doubleSubmission.uploadErrorFunction) {
// 関数登録されていれば呼び出す
sde.doubleSubmission.uploadErrorFunction();
}

};
No.8.2.10(1) 検査ソフト 実施環境No.1 検査日時 2024/11/26 実施者 MSE大内 目的 マスクにて受信設定されているIDを、突発的に連続受信した時に、取りこぼしが発生しないことを確認する 確認方法 ①送信停止のテスト用コードを作成する。 下記、「送信停止テストコード追加位置」を参照    (a)NMフレーム確認 ②-(a)受信値確認のテスト用コードを作成する。 下記、「受信値確認テストコード追加位置」を参照 ③-(a)CAPLを使用して、車両通信仕様に定義されているNM搭載ノードの送信NMフレームを全て一斉に送信する。    ※一斉送信時の送信間隔を、CANoe(またはオシロスコープ)にて確認すること。     期待値は、フレーム長+3bit(CANプロトコルに規定のフレーム間隔)で、228μs。 下記、「測定方法」を参照 ④-(a)送信データと、受信値が一致することを確認する。    (b)フレーム確認(フレーム受信にIDマスクを使用している場合のみ実施。IDマスク使用有無は設計者に確認すること) 2024/11/21 MSE大内 ②-(b)CAPLを使用して、車両通信仕様に定義されており、かつ、IDマスクを使用して受信する    他ノードの送信フレームを全て一斉に送信する。     ※一斉送信時の送信間隔を、CANoe(またはオシロスコープ)にて確認すること。      期待値は、フレーム長+3bit(CANプロトコルに規定のフレーム間隔)      例)500kbpsでDLC=8のフレームの場合:222μs+6μs=228μs 下記、「測定方法」を参照 ③-(b)受信データをRAM値で確認して、送信データと一致することを確認する。 ③ 測定方法 前提条件 下記の条件を満たすCANoeコンフィグをベースとして使用すること。 ・ ユーザからパネル等のへの操作をしない限り、CAN出力(METからの信号等への応答を含む)しないこと。 準備 8.2.9(1)_8.2.10(1)_8.2.15(8)CAPL作成補助ツール.xls を参照し、CAPLの作成とCANoeコンフィグへの組込みを実施する。(他シートで組込み済みの場合は実施不要) 測定 ■(a)NMフレーム確認 (1) CANoeをRUNし、測定を開始する。 (2) メータを+B ONする。(CANoeはIG-ONしない) (3) CANoeのロギングを開始する。ロギング対象は全フレームとする。 (4) キーボードの'n'キーを押下し、CAPLによるフレーム送信を開始する。 (5) (4)の後、登録したNMフレームがすべて送信されるまで待つ。 (6) 終了後、CAPLから一斉送信したときのフレーム間隔とMETが送信するフレームの送信間隔を確認する。 (7) SoftuneにてRAM値を確認し、CANoeが送信した信号と一致するかを確認する。 ■(b)フレーム確認 (1) CANoeをRUNし、測定を開始する。 (2) メータをIG-ONする。(CANoeはIG-ONしない) (3) CANoeのロギングを開始する。ロギング対象は全フレームとする。 (4) キーボードの'm'キーを押下し、CAPLによるフレーム送信を開始する。 (5) (4)の後、登録したフレームがすべて送信されるまで待つ。 (6) 終了後、CAPLから一斉送信したときのフレーム間隔とMETが送信するフレームの送信間隔を確認する。 (7) SoftuneにてRAM値を確認し、CANoeが送信した信号と一致するかを確認する。 確認結果 一斉送信時のフレーム間の平均送信間隔 μs 送信するNMフレームをここに記述して下さい 受信データ 判定 ↓ ★↓弊社情報のため、詳細RAM名は記載省略します。 No. NM搭載ノード CAN-ID DLC DATA RAM名 CANID DLC DATA 判定 1 - - - - - 2 - - - - - 3 - - - - - 4 - - - - - 5 - - - - - 6 - - - - - 7 - - - - - 8 - - - - - 9 - - - - - 10 - - - - - 11 - - - - - 12 - - - - - ■SPF 一斉送信時のフレーム間の平均送信間隔 219.3 μs 送信するフレームをここに記述して下さい 確認結果 判定 ↓ ★↓弊社情報のため、詳細RAM名は記載省略します。 ID設定 Msg. Label CAN-ID Sub ID DLC DATA RAM名 CANID DLC DATA 判定 結果 実施日 実施者 実施環境 - SCM1S07 51F - 8 11 22 33 44 55 66 77 08 spf_scom_com_RMBuf_SCM1S07 51F 8 11 22 33 44 55 66 77 08 ○ OK 2024/11/26 MSE大内 1 マスク設定 - OK 1 NG→OK 0 NG 0 保留 0 BK 0 OT 0 未着 0
11-22
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值