금백조의 개발 블로그

[JavaScript]JSP에서 JavaScript로 EL(Expression Language)값 할당 방법(2021-09-20 내용추가) 본문

Web/JavaScript

[JavaScript]JSP에서 JavaScript로 EL(Expression Language)값 할당 방법(2021-09-20 내용추가)

금백조 2021. 2. 21. 17:18
반응형

서론

 

진행 중인 Spring 웹 사이드 프로젝트에서 서버에서 전달받은 EL표현식으로 된 값(JSON 형식)을 JavaScript 내에서 할당할 방법을 찾고 있었습니다. 이 과정 속에서 알게 된 JavaScript로 EL값을 표현하는 방법과 발생했던 이슈사항 및 해결법에 대해 작성해볼까 합니다.

 


 

본론

 

만약 아래와 같이 서버에서 게시판의 게시글 정보를 JSON 형태로 전달해준 EL값이 ${PostData}라고 가정해보겠습니다.

 

[${PostData}]

 

{
    "post":[
       {
          "title":"게시글1",
          "content":"내용1"
       },
       {
          "title":"게시글2",
          "content":"내용2"
       },
       {
          "title":"게시글3",
          "content":"내용3"
       },
       {
          "title":"게시글4",
          "content":"내용4"
       }
     ]
}

 

처음에 저는 단순히 ${PostData} 자체를 JavaScript 변수에 할당하는 방법을 생각했습니다. 

 

[JavaScript로 EL값을 할당하기 위해 처음 시도했던 방법]

 

var param = ${PostData};//${PostData} 값이 있는 경우 값이 정상적으로 할당됨.

 

이 방법은 ${PostData}의 값이 존재할 때는 문제가 되지 않았으나 ${PostData} 값이 존재하지 않을 경우 JavaScript 문법 에러를 발생시켰습니다.

 

[EL값이 존재하지 않을 경우 위 방식으로 했을 때 실제 동작하는 JavaScript 코드]

 

var param = ;//${PostData} 값이 아예 존재하지 않으므로 문법 에러 발생

 

아래와 같이 크롬 개발자 도구에서 보면 문법 에러가 나타남

 

따라서 EL값이 존재하지 않을 경우 예외 처리할 방법을 찾던 도중 JSTL의 <c:out> 태그를 사용하여 값을 할당 후 JSON.parse 를 사용하여 <c:out> 태그로 출력한 JSON 문자열을 JSON으로 변환해주었습니다.

 

[<c:out> 태그를 통한 값 할당]

 

var param = '<c:out value='${PostData}'/>';
param = JSON.parse(param);//<c:out>에 의해 "이 &#034;로 변환되었으므로 값 생성 X

 

위의 방식대로 할 경우 ${PostData}의 값이 존재하지 않을 때는 param 이 ''로 처리되어 발생하던 문법 에러는 해결됐습니다. 그러나 다른 문제가 발생했습니다. JSON 형식은 " 인 큰 따옴표를 포함합니다. 그러나 <c:out>은 보안상의 이유로 자체적으로 "을 &#034;로 변환되기 때문에 아래와 같이 값이 할당되어 버립니다.

 

[<c:out>을 통해 실제 할당된 param 값]

 

//<c:out>으로 인해 "가 &#034;로 변환됨.
var param = 
'{
    &#034;post&#034;:[
       {
          &#034;title&#034;:&#034;게시글1&#034;,
          &#034;content&#034;:&#034;내용1&#034;
       },
       {
          &#034;title&#034;:&#034;게시글2&#034;,
          &#034;content&#034;:&#034;내용2&#034;
       },
       {
          &#034;title&#034;:&#034;게시글3&#034;,
          &#034;content&#034;:&#034;내용3&#034;
       },
       {
          &#034;title&#034;:&#034;게시글4&#034;,
          &#034;content&#034;:&#034;내용4&#034;
       }
     ]
}';

 

따라서 &#034; 문자열로 인해 JSON.parse가 JSON 형식을 인식하지 못하기에 &#034; 문자열 전체를 "로 변환하여 문제를 해결했습니다.

 

[문자열 &#034; 을 " 로 변환하여 문제 해결 방법]

 

var param = '<c:out value='${PostData}'/>';
param = param.replace(/&#034;/g,'"');//&#034;전체를 "로 변환
param = JSON.parse(param);

 

그러나 이 방법은 &#034; 문자열 전체를 "로 치환하므로 그만한 비용을 감당해야 했습니다. 소규모 데이터에서는 크게 차이가 안 나겠지만 대규모 데이터에서는 성능상 문제가 될 수도 있다고 생각하여 더 좋은 방법이 있을까 생각해보았습니다. 그러던 중 <c:out> 태그의 escapeXml 속성 값을 false로 주어 " 문자가 &#034; 로 치환되지 않도록 하여 문제를 해결해보았습니다.

 

[escapeXml 속성값을 false로 주어 문제 해결 방법]

 

var param = '<c:out value='${PostData}' escapeXml = "false"/>';// "가 &#034;로 변환되지 않음
param = JSON.parse(param);

 

위의 방법은 문자열을 변환할 필요가 없어집니다. 그러나 XSS(Cross Site Scripting) 공격을 막기 위해 <c:out>에서 스크립트 실행 위험성이 있는 [> , < , & , ' , "]을 [&lt; , &gt; , &amp; , &#039; , &#034;]으로 치환하는 기능을 제거한 것이기 때문에 보안상 취약해질 수 있는 단점이 있습니다. 따라서 [문자열 &#034; 을 " 변환하여 문제 해결 방법]이 보안상 더 안전한 방법이라고 생각됩니다.

 

2021-09-20 내용추가

[EL표현식 양쪽에 ' 작은따옴표를 넣어서 해결]

 

var param = '${PostData}';

 

이게 가장 좋은 해결 방법인 것 같습니다. 이렇게 하면 첫번째 문제도 해결되고 문자열 처리를 안해줘도 되네요. 간단하게 양쪽 쌍따옴표만 붙여주면 될 문제를 빙빙 돌아서 해결하려 했던거 같네요... JavaScript 내에서 EL 표현식을 쓸 땐 꼭 양쪽에 따옴표를 붙여주세요!

 


 

결론

 

사이드 프로젝트를 진행하며 알게 된 JavaScript에서 EL값을 할당하는 방법을 정리해보았습니다. 이 외에도 더 좋은 방법이 있을 것 같은데 댓글로 공유해주시면 감사하겠습니다!

 

Reference

 

[Xion] - [JSP]<c:out>을 사용하는 이유

2ham-s.tistory.com/274

 

반응형