1. 사용 배경
1) Ajax를 컨트롤할 때 각종 옵션을 개발자 및 화면마다 다 직접 입력하다보니 Csrf, Xss 등의 보안 처리를 개별적으로 하다보면 오류 발생시 대처 어려움
2) 이러한 현상으로 인해 개발자마다 개발 방식의 공통 부재는 기본이거니와 유지보수 때에도 추적이 어렵다. (유지보수비용 과다 발생 원인 중 하나)
2. 사용 방법
1) 아래 소스를 이용하고자한다면 서버에서 Exception 오류등의 발생시 무조건 동일 구조로 Response를 내려주는 기본 인터페이스가 선행되어야한다.
필자의 경우 Java를 이용 중이므로 GlobalExceptionHandler 및 Jackson Json을 이용하여 공통 Vo를 사용하여 아래 구조를 필히 응답한다.
/** 웹 API 커스텀 */
const ajax = {
logPrefix: "[ADMIN-API] -- "
, params: {
type: 'POST'
, contentType: 'application/json;'
, dataType: 'json'
, includeHeader: true
, hasLoading: true
, errAlert: false
, data: {}
, beforeSend: function (xhr) {
xhr.setRequestHeader(app.csrf.headerName, app.csrf.token);
}
}
, call: function (opts) {
// 고정 변수를 복제한다.
let ajaxParams = _.clone(ajax.params);
// 기존 Ajax Options 정보를 덮어 씌운다.
_.extend(ajaxParams, opts);
console.log(ajax.logPrefix + "Request Start");
console.log(ajax.logPrefix + "Request - " + ajaxParams.url);
if (typeof ajaxParams.data === 'object') {
let data = JSON.stringify(ajaxParams.data, null, 4);
console.log(ajax.logPrefix + "Request params - " + data);
ajaxParams.data = data;
}
ajaxParams.success = function (resultData, status, xhr) {
let resParam = {
"type": 1
, "ajaxParams": ajaxParams
, "userOpts": opts
, "resultData": resultData
, "status": status
, "xhr": xhr
}
ajax.callSuccessAction(resParam);
};
ajaxParams.error = function (xhr, status, errorThrown) {
let resParam = {
"type": -1
, "ajaxParams": ajaxParams
, "userOpts": opts
, "resultData": xhr.responseText
, "status": status
, "xhr": xhr
, "errorThrown": errorThrown
}
console.log(ajax.logPrefix + "Response : Error - ", xhr, status, errorThrown);
ajax.callFailureAction(resParam);
};
ajaxParams.complete = function (xhr) {
console.log(ajax.logPrefix + "===============[ End ]==");
};
$.ajax(ajaxParams);
}
/***************************************************************************
* @param {
"ajaxParams": ajaxParams
, "userOpts": opts
, "resultData": resultData
, "status": status
, "xhr": xhr
}
*/
, callSuccessAction: function (param) {
// Function이 구현되어있는 경우.
try {
let header = param.resultData.header;
let body = param.resultData.body;
let ajaxParams = param.ajaxParams;
let userParams = param.userOpts;
console.log(ajax.logPrefix + "Response : success - ", JSON.stringify(body, null, 4));
if (header.isSuccess) {
if (ajaxParams.includeHeader) {
userParams.success(param.resultData, param.status, param.xhr)
} else {
userParams.success(body, param.status, param.xhr);
}
// 무조건 Complete 실행
ajax.callCompleteAction(param)
} else {
// Failure 구현식을 Function 아닌 경우
throw cmm.getMessageCode(-100);
}
} catch (e) {
console.error("ERR - ", e);
param.errorThrown = e;
ajax.callFailureAction(param);
return;
}
}
/***************************************************************************
* @param {
"ajaxParams": ajaxParams
, "userOpts": opts
, "resultData": xhr.responseText
, "status": status
, "xhr": xhr
, "errorThrown": errorThrown
}
*/
, callFailureAction: function (param) {
console.log(ajax.logPrefix + "Response : failure - ", JSON.stringify(param, null, 4));
let json;
try {
if (typeof param.resultData == 'object') {
json = param.resultData;
} else if (typeof param.resultData == 'string') {
json = JSON.parse(param.resultData);
} else {
json = new Object();
}
if (param.ajaxParams.errAlert) {
alert(json.header.message);
}
_.isFunction(param.userOpts.error) ? param.userOpts.error(json) : function () {
alert(json.header.message);
let forwardUrl = json.header.forwardUrl;
if (!_.isEmpty(forwardUrl)) {
location.href = forwardUrl;
}
};
} finally {
ajax.callCompleteAction(param);
}
}
, callCompleteAction: function (param) {
// Function이 구현되어있는 경우.
if (_.isFunction(param.userOpts.complete)) {
param.userOpts.complete();
} else {
// TODO 필요시 공통 구현. (현재는 사용용도 없음)
}
}
};
3. 결과
1) 성공
{
header: {
resultCode : 1 or -1
,resultDetailCode : 100 or 200
,message : "SUCCESS" OR "FAIL"
}
, result : Array or Object
}
2) 실패
{
"header" : {
"isSuccess" : false,
"statusCode" : -1,
"statusDetailCode" : 401,
"message" : "Permission is Not Empty"
}
}
'Programming > 기본 (Baisc)' 카테고리의 다른 글
[GIt][깃랩][Gitlab] 대용량 파일 Push Commit 방법 (0) | 2021.12.06 |
---|---|
[메이븐][Maven] 폐쇄망 환경 SSL 인증서 전체 허용 설정 (2) | 2021.12.02 |
[자바스크립트][Javascript] Jwplayer Html5 Video Player 배속, 배율 재생 (0) | 2021.11.30 |
[유틸[Util] Javascript(JS) Cookie 제어 유틸 (0) | 2021.11.08 |
[ORACLE] PL/SQL Procedure 또는 DECLARE에서 DDL 사용하기. (0) | 2021.11.07 |