'소프트웨어개발/웹'에 해당되는 글 8건

  1. AJAX 요청에 대한 CORS 허용하기
  2. HTTP GET 요청시 전달 가능한 파라메터의 최대 크기와 고려할 점은?
  3. INPUT 엘러먼트 제어하기
  4. Select2, AutoComplete을 지원하는 select 확장 플러그인 (2)
  5. Bootstrap 3 기본 뼈대 페이지 만들기 (1)
  6. Bootstrap 3, Table에 가로형 스크롤바 삽입하기
  7. Bootstrap에 날개를 달아주는 리소스, 플러그인 소개
  8. 웹에서 Responsive Image(반응형 이미지) 구현하기

AJAX 요청에 대한 CORS 허용하기

Origin이란?

Origin은 아래와 같이 protocol, host, port 3개 부분으로 구성된다.

http://www.jsonobject.com:8080/
# protocol: http
# host: www.jsonobject.com
# port: 8080
  • 2개의 Origin을 비교시 3개 부분 중 단 1개만 일치하지 않아도 서로 다른 Origin이 된다. 즉, http, https의 차이, 80, 8080의 차이만 나도 서로 다른 Origin이 된다.

브라우저에서 현재 페이지의 Origin 알아내기

브라우저에서 현재 페이지의 정확한 Origin을 알고자 한다면 JavaScript에서 아래 명령을 실행한다.

# IE를 제외한 모든 브라우저
window.location.origin

# IE
window.location.protocol + '//' + window.location.hostname + ':' + window.location.port
  • 브라우저에 따라 현재 페이지의 Origin을 획득하는 방법은 위와 같이 2가지로 구분된다.

CORS

기본적으로 브라우저는 현재 페이지에서 Origin이 다른 URL로의 AJAX 요청을 원천적으로 차단한다.


  • 사실 브라우저는 Origin이 다른 URL에 대한 AJAX 요청 후 응답을 이미 받은 상태로 응답 헤더 CORS 정보를 확인하여 차단하는 것이다.

  • CORS란 무엇일까? CORS(Cross Origin Resource Sharing)는 서로 다른 Origin 간의 AJAX 요청-응답을 서버에서 제어할 수 있도록 만들어진 W3C의 표준이다. 요청을 받는 서버 측은 CORS 정책을 명시하여 클라이언트에 따라 AJAX 요청을 허용할지 말지를 결정할 수 있다.

  • 최근 유행하는 토큰 인증 기반의 웹 애플리케이션의 구조는 페이지(https://app.jsonobject.com) 상에서 API 서버(https://api.jsonobject.com)로 바로 AJAX 요청을 하는 구조로 진행되기에 AJAX 요청을 받는 서버 측에서 클라이언트의 Origin을 허용하는 작업이 필요하다. 서버에서 응답 헤더에 아래 정보를 추가하면 된다.
# AJAX 요청을 허용할 클라이언트의 Origin을 명시한다.
Access-Control-Allow-Origin: https://app.jsonobject.com

# Origin의 구분 없이 모든 클라이언트로부터 AJAX 요청을 허용한다.
Access-Control-Allow-Origin: *

참고 글

저작자 표시 비영리 동일 조건 변경 허락
신고

HTTP GET 요청시 전달 가능한 파라메터의 최대 크기와 고려할 점은?

HTTP GET 요청시 파라메터의 최대 크기 = URI의 최대 크기

클라이언트에서 HTTP GET 요청시 파라메터는 고스란히 URI에 포함되어 브라우저를 통해 서버에 전달된다. 이러한 HTTP GET 요청 방식의 특성상 전달 가능한 파라메터의 최대 크기는 곧 브라우저에서 허용 가능한 URI의 최대 크기가 된다.

  • 허용되는 URI의 최대 크기는 2083~6200byte로 브라우저마다 제각각이다. 따라서 HTTP GET 요청은 이 점을 고려하여 신중하게 설계해야 한다. 전달할 파라메터가 크기가 크다고 판단되면 GET보다는 HTTP POST 요청을 하는 것이 안전하다.
  • RFC 문서에 의하면 전달할 파라메터의 크기가 브라우저의 허용치보다 클 경우 URI가 잘린 채 전송되거나 서버로부터 414 Request-URI Too Long 오류를 반환받게 된다.(실제 테스트 결과 400 Bad Request 오류를 반환받았다.)
  • 또한 HTTP GET 요청에 담기는 파라메터는 고스란히 URI를 통해 노출되기 때문에 보안에도 적절하지 않다. 페이지 갱신에 필요한 최소한의 데이터를 제외하고는 URI에 노출되어서는 안된다.

참고 글


저작자 표시 비영리 동일 조건 변경 허락
신고

INPUT 엘러먼트 제어하기

웹 애플리케이션의 프론트엔드 화면을 개발하다보면 가장 빈번하게 사용하는 것이 사용자로부터 검색조건이나 등록할 정보를 입력받는 input 엘러먼트이다. 가장 많이 사용되는 text 타입과 select 엘러먼트를 예로 들어 간단한 input 엘러먼트 제어 방법을 정리하였다.

HTML 선언하기

<!-- 활성화된 TextBox를 선언한다. -->
<input id="someText" type="text" placeholder="someText">

<!-- 비활성화된 TextBox를 선언하려면 disabled 애트리뷰트를 부여한다. -->
<input id="someText" type="text" placeholder="someText" disabled>

<!-- ComboBox도 비활성화가 가능하다. -->
<select id="someSelect" disabled>
  <option value="KOR">Korea</option>
  <option value="CHN">China</option>
  <option value="JPN">Japan</option>
</select>

JavaScript에서 제어하기

jQuery에서는 아래와 같이 input 엘러먼트에 대한 제어가 가능하다.

// TextBox를 비활성화한다. INPUT 엘러먼트로 선언할 수 있는 모든 타입의 컨트롤이 가능하다.
$('#someText').prop('disabled', true);

// TextBox를 활성화한다.
$('#someText').prop('disabled', false);

// TextBox의 현재 입력 값을 획득한다. 역시 INPUT 엘러먼트로 선언할 수 있는 모든 타입의 컨트롤이 가능하다.
var someText = $('#someText').val();

// TextBox의 입력 값을 임의로 부여한다.
$('#someText').val('someValue');

// ComboBox의 입력 값을 임의로 부여한다. OPTION 엘러먼트에 존재하지 않는 값을 부여할 경우 값이 초기화된다.
$('#someSelect').val('CHN');

// TextBox의 입력 값을 초기화한다.
$('#someText').val('');


저작자 표시 비영리 동일 조건 변경 허락
신고

Select2, AutoComplete을 지원하는 select 확장 플러그인

1% 부족한 select 엘러먼트

HTML5에서는 select 엘러먼트를 이용하여 ComboBox 컨트롤을 구현할 수 있다. 하지만 기본 엘러먼트만으로는 기대치가 높은 사용자의 까다로운 요구를 수용하기에 기능이 너무 부족하다.(사실 이 글을 작성하게 된 계기도 사용자의 자동완성 기능 구현 요구 때문이었다.^^) 이런 select 엘러먼트의 부족한 기능을 강화시켜주는 애드온 성격의 라이브러리가 많은데 이번 글에서는 많이 사용되는 Select2 라이브러리의 기본적인 사용법을 설명하고자 한다.

Select2 특징

본격적으로 사용법을 정리하기에 앞서 Select2 라이브러리의 기본적인 특징은 아래와 같다.

  • 자동완성(AutoComplete)AJAX를 이용한 원격 데이터 불러오기가 가능하다. 자동완성의 경우 한글은 문자 단위부터 가능하며 초성은 지원되지 않는다.
  • jQuery 기반의 플러그인으로 jQuery가 필수이다.
  • Bootstrap 테마를 지원하여 위화감 없이 사용이 가능하다.
  • GPL v2 라이센스이다. 상업적인 목적의 수정이 아닌 이상 무료 사용이 가능하다.

라이브러리 로드

Select2 라이브러리는 아래와 같이 로드한다. 아래는 예를 보여주기 위해 공식 홈페이지의 경로에서 바로 로드하였는데 프로젝트에 사용할 경우 압축 파일을 다운로드하여 적절한 위치에 저장 후 임포트해서 사용하도록 한다.

<link href="https://ivaynberg.github.io/select2/select2-3.5.1/select2.css" rel="stylesheet"/>
<script src="https://ivaynberg.github.io/select2/select2-3.5.1/select2.js"></script>

기본 사용법

Select2(v3.5.1 기준) 라이브러리의 기본적인 사용 방법은 아래와 같다. 가장 먼저 HTML에 출력될 부분을 선언한다.

<div id="someSelect"></div>
  • HTML 상에서 사용자에게 출력될 데이터를 명시하지 않고 JavaScript 상에서 원격 데이터를 로드하려면 select 엘러먼트를 사용하지 말고 div 엘러먼트를 사용해야 한다.

JavaScript 상에서는 아래와 같이 초기화한다.

// 원격 데이터를 부여하여 select 엘러먼트를 초기화한다. 이 작업으로 기본 셋업은 끝났다.
var data = [{
  id: 'KOR',
  text: 'Korea'
}, {
  id: 'JPN',
  text: 'Japan'
}];

$('#someSelect').select2({
  data: data,
  width: '100%'
});
  • data는 배열 형태로 각 배열의 요소는 idtext를 가진 오브젝트이어야 한다.
  • width는 화면에 출력될 Select 엘러먼트의 크기로 픽셀 또는 퍼센트로 지정이 가능하다.
실행 결과는 아래와 같다. 자동완성(AutoComplete) 기능이 적용되는 것을 확인할 수 있다.


선택 값 획득 및 설정하기

// 사용자가 선택한 값을 획득한다. 어떤 값도 선택하지 않았을 경우 ''을 반환한다.
var someValue = $('#someSelect').select2('val');

// select 엘러먼트의 선택 값을 받는 일반적인 방법으로도 획득이 가능하다.
var someValue = $('#someSelect').val();

// 코드 레벨에서 임의의 값을 선택한다.
// 임의의 값 선택시 기존 데이터 배열에 존재하지 않는 값이면 '' 값이 설정된다.
$('#someSelect').select2('val', 'someValue');

비활성화 및 활성화하기

때때로 다른 select 엘러먼트의 결과에 따라 select 엘러먼트를 비활성화하거나 활성화할 필요가 있다. 아래와 같이 코드 레벨에서 비활성화 및 활성화가 가능하다.

// 값을 초기화한다.
$('#someSelect').select2('val', '');
// 비활성화한다.
$('#someSelect').select2('enable', false);
// 활성화한다.
$('#someSelect').select2('enable', true);

// 문서 로드시 처음부터 비활성화된 채로 select 엘러먼트를 초기화해두려면 아래와 같이 작성한다.
$('#someSelect').select2({
  data: [{}],
  width: '100%'
});
$('#someSelect').select2('val', '');
$('#someSelect').select2('enable', false);

// 아래와 같이 jQuery의 플러그인으로 만들 수도 있다. 플러그인을 만드는 방법이 사용에 있어 훨씬 편리하다.
$.fn.select2Disabled = function() {
  $(this).select2({
    data: [{}],
    width: '100%'
  });
  $(this).select2('val', '');
  $(this).select2('enable', false);
};

// 앞서 작성한 비활성화 플러그인을 호출한다.
$('#someSelect').select2Disabled();

// 새로운 데이터를 로드하면서 활성화하는 플러그인도 만들어두면 편리하다. data와 callback 메써드를 매개변수로 두어 확장성을 높였다.
$.fn.select2Enabled = function(data, callback) {
  $(this).select2('val', '');
  $(this).select2('enable', true);
  $(this).select2('destroy');
  $(this).select2({
    data: data,
    width: '100%'
  });
  $(this).on('select2-selecting', callback);
};

한글화

Select2 라이브러리는 기본적으로 한글화 언어팩을 제공하지만 자신만의 커스터마이징된 한글화도 가능하다. 아래는 내가 필요로 하는 문자열만 한글화하였다.

(function($) {
  "use strict";
  $.fn.select2.locales['ko'] = {
    formatNoMatches: function() {
      return "데이터가 없습니다.";
    }
  };
  $.extend($.fn.select2.defaults, $.fn.select2.locales['ko']);
})(jQuery);

그 밖의 팁

가독성을 위해 셀렉트 엘러먼트 클릭시 출력되는 옵션 목록의 글꼴을 고정폭 글꼴로 변경하려면 아래와 같이 CSS를 설정한다.

.select2-result-label {
  font-family: '돋움체' !important;
}

대부분의 경우 Select2의 데이터 소스는 하드 코딩보다는 원격 데이터베이스에서 쿼리 결과를 바인딩하는 형태로 사용한다. 데이터 바인딩을 돕는 유틸리티 오브젝트를 아래와 같이 만들어봤다.

// Select2Util은 Select2를 보완하는 유틸리티 오브젝트이다.
var Select2Util = {
  // 1개 컬럼(id) 또는 2개 컬럼(1번째 컬럼은 id, 2번째 컬럼은 text) 구조를 가진 원격 데이터 배열을 Select2의 원격 소스로 사용되는 data 형식으로 변경한다.
  // 멀티 컬럼을 지원하지 않는 단점을 보완하기 위해 text에 id 값을 포함하도록 가공한다.
  //
  // ex) KEY  VALUE  ->  id   text
  //     ----------      ----------------
  //     KOR  Korea      KOR  [KOR] Korea
  //     JPN  Japan      JPN  [JPN] Japan
  //
  // ex) var data = Select2Util.toData(anyData);
  //
  toData: function(data) {
    if (!Array.isArray(data)) {
      return new Array();
    }
    if (data.length === 0) {
      return new Array();
    }
    var keyNames = Object.getOwnPropertyNames(data[0]);
    if (keyNames.length > 2) {
      return new Array();
    }
    var id = keyNames[0];
    var text = keyNames[0];
    if (keyNames.length == 2) {
      text = keyNames[1];  
    }
    var newData = new Array();
    for (var i = 0; i < data.length; i++) {
      var newObject = {};
      newObject['id'] = data[i][id];
      newObject['text'] = data[i][text];
      if (keyNames.length == 2) {  
        newObject['text'] = '[' + data[i][id] + '] ' + data[i][text];
      }
      newData.add(newObject);
    }
    return newData;
  },
  // Select2의 원격 소스로 사용되는 data 배열에 새로운 오브젝트를 추가한다.
  //
  // ex) Select2Util.addData(oldData, {id : 'CHN', text: 'CHINA');
  //
  addData: function(data, newData) {
    var object = data.find(function(n) {
      return n['id'] == newData['id'];
    });
    if (typeof object === 'undefined') {
      data.add({
        id: newData['id'],
        text: '[' + newData['id'] + '] ' + newData['text']
      });
    }
    return data;
  }
};


저작자 표시 비영리 동일 조건 변경 허락
신고

Bootstrap 3 기본 뼈대 페이지 만들기

JavaScript 공부, Bootstrap과 함께 시작해보자

JavaScript를 공부하는데 있어 가장 중요한 것은 자주 많이 코드를 작성해봐야 한다는 것이다. 하지만 Hello, World! 문구 하나를 찍더라도 화면에 출력하는 방법은 천차만별인 법이다. 나는 JavaScript를 처음 공부하는 사람에게 Bootstrap을 기반으로 코드를 작성할 것을 추천한다. 마치 Java 입문시 콘솔보다는 Swing을 이용하여 Hello, World!를 화면에 출력하는 것과 같은 이치이다.

기본 뼈대 페이지 작성하기

Bootstrap 3 기반의 기본 뼈대 페이지는 아래와 같다.


<!DOCTYPE html>
<html lang="ko">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title></title>
  <link href="http://getbootstrap.com/dist/css/bootstrap.min.css" rel="stylesheet"/>
  <link href="http://getbootstrap.com/assets/css/docs.min.css" rel="stylesheet"/>
  <link href="https://paypal.github.io/bootstrap-accessibility-plugin/plugins/css/bootstrap-accessibility.css" rel="stylesheet"/>
  <style>
    * {
      font-family: 'Malgun Gothic' !important;
    }
  </style>
</head>
<body>
  <!-- HTML -->
  <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
  <script src="http://getbootstrap.com/dist/js/bootstrap.min.js"></script>
  <script src="http://getbootstrap.com/assets/js/docs.min.js"></script>
  <script src="https://paypal.github.io/bootstrap-accessibility-plugin/plugins/js/bootstrap-accessibility.min.js"></script>
  <script>
    // JavaScript
  </script>
</body>
</html>
  • 문서의 구조는 전형적인 HTML5 구조이다. 문자셋은 UTF-8이기 때문에 파일 저장시 UTF-8로 저장해야 한글이 깨지지 않는다.
  • jQuery, Bootstrap, Bootstrap Accessibility Plugin이 순서대로 기본 셋업에 사용되었다. 웹사이트 구축보다는 JavaScript 공부에 초점을 맞추어 서버에서 바로 모든 라이브러리를 로드하기 때문에 별도로 다운로드할 필요가 없다. JavaScript 라이브러리 로드는 문서의 마지막에 로드하는 Lazy Loading 기법을 사용하였다.
  • 기본 글꼴로 굴림보다 가독성이 좋은 맑은 고딕을 사용하였다.


저작자 표시 비영리 동일 조건 변경 허락
신고

Bootstrap 3, Table에 가로형 스크롤바 삽입하기

반응형이냐 고정형이냐의 고민

Bootstrap 3 환경에서 Table 엘러먼트를 구현시 반응형(responsive)으로 할 것이냐 고정형(fixed)으로 할 것이냐를 고민할 때가 많다. 대세는 반응형이라고 하지만 기업에서 구현하는 시스템의 대부분은 상당히 많은 수의 컬럼을 가진 데이터를 화면 상의 테이블에 출력해야 하는 경우가 많기 때문에 반응형으로 구현하는데 한계가 있다. 이 글에서는 Bootstrap 플랫폼에서 Table 을 반응형 또는 고정형으로 구현하는 방법을 설명하겠다.

첫째, 반응형으로 구현하기

테이블을 반응형으로 구현하는 것은 어렵지 않다. Bootstrap 공식 레퍼런스에서 제시하는 방법은 아래와 같다. 가장 많이 사용하는 방법이다.


<div class="table-responsive">
  <table class="table">...</table>
</div>
  • 첫째, 테이블을 구현할 table 엘러먼트에 table 클래스를 부여한다.
  • 둘째, table 엘러먼트를 감싸는 div 엘러먼트를 생성하고 table-responsive 클래스를 부여한다.
  • 이 방법은 화면의 가로 길이가 768px 이하일 때만 작동한다는 것을 염두해야 한다. 화면의 가로 길이가 768px 이상일 경우에는 변화하는 화면 크기에 맞게 컬럼의 크기가 유동적으로 변한다. 768px 이하가 되면 컬럼 크기가 고정되고 테이블 하단에 가로 방향의 스크롤바가 생성된다.

둘째, 고정형으로 구현하기

고정형으로 구현하는 것은 내가 생각한 일종의 트릭이다. 방법은 아래와 같다.


<div class="fixed-table-container">
  <div class="fixed-table-body">
    <table class="table">...</table>
  </div>
</div>
  • 테이블을 구현할 table 엘러먼트를 2번에 걸쳐 감싸는 것 말고는 큰 차이점은 없다.
  • 위와 같이 구현하면 테이블의 가로 길이가 화면 길이를 초과할 경우 초과되는 부분은 잘려버린다. 이 현상을 막기 위해 Bootstrap에 미리 정의된 CSS를 아래와 같이 오버라이드(override)한다.
.fixed-table-body {
  overflow-x: auto;
}
  • overflow-x 애트리뷰트의 기본값은 hidden으로 되어있다. auto로 변경함으로써 필요한 경우에만 테이블 하단에 가로 방향의 스크롤바가 보여지게 하는 것이다.
  • 이 방법은 앞서 반응형 방식과 다르게 화면의 가로 길이와 무관하게 항상 적용된다. 테이블의 가로 길이가 화면 길이보다 클 경우에만 스크롤바가 생성된다.
  • Bootstrap Table 플러그인을 사용한다면 이 방법을 권장한다. 플러그인이 가진 복잡성과 구조적 특성으로 인해 반응형 방식으로의 구현이 불가능하다.


저작자 표시 비영리 동일 조건 변경 허락
신고

Bootstrap에 날개를 달아주는 리소스, 플러그인 소개

개발자들의 구세주, Bootstrap

Bootstrap은 웹 프론트엔드 프레임워크이다. HTML5/CSS3/JavaScript 각 언어로 제공되는 템플릿 소스 코드를 이용하여 디자인에 관한 전문 지식 없이도 반응형 웹 기반의 미려한 사이트를 구축할 수 있어 국내외에서 광범위하게 사용되고 있다. 극단적인 경우 class 애튜리뷰트만 지정해서 초고속으로 개발해도 미려한 화면이 나온다. 훨씬 먼저 시작된 프로젝트인 jQuery UI, jQuery Mobile의 존재감을 무색하게 할 정도로 압도적으로 사랑받고 있다. 일각에서는 Bootstrap이 웹의 다양성을 해쳤다는 비판도 있지만 시간과 생산성이 생명인 백엔드 중심의 개발자들에게 있어 Bootstrap은 구세주와도 같다. 라면도 계란과 파를 첨가하면 더 맛있게 먹을 수 있듯이 Bootstrap도 그대로 사용하는 것보다 여러 부가적인 플러그인을 활용하면 손쉽게 훨씬 미려한 웹 사이트 구축이 가능하다. 아래 Bootstrap의 생산성을 향상시켜주는 유용한 리소스 및 플러그인을 정리해봤다.

리소스

Bootstrap

BootstrapBootstrap의 공식 홈페이지로 다운로드 및 튜토리얼을 제공한다. 현재 최신 버전은 v3이다.


Bootsnipp

BootsnippBootstrap만을 다루는 일종의 포탈 같은 사이트이다. 디자인 갤러리, 사이트 북마크, 플러그인 소개 등의 Bootstrap 관련 유용한 정보를 제공한다.


Bootstrap Hero

Bootstrap Hero 역시 유용한 사이트와 플러그인 정보를 제공한다.


플러그인

Bootstrap Accessibility Plugin

Bootstrap Accessibility PluginPayPal에서 공개한 접근성 강화 플러그인이다. 마우스가 없는 환경에서 Bootstrap의 키보드 이동 기능을 강화했다. Bootstrap v3를 지원하며 BSD License이다.


Bootbox.js

Bootbox.js은 평범하고 심심한 window.alert(), window.confirm(), window.prompt() 메써드를 화려한 Bootstrap 스타일로 탈바꿈시켜주는 플러그인이다. Bootstrap v3를 지원하며 MIT License이다.


X-editable

X-editable은 평범한 div 엘러먼트를 체크박스 및 다중 선택, 날짜 등의 데이터 입력 및 수정이 가능한 오브젝트로 탈바꿈시켜준다. Bootstrap v3를 지원하며 MIT License이다.


Bootstrap Table

Bootstrap Table은 최근 가장 활발하게 개발되고 있는 Table 기능 강화 플러그인이다. Bootstrap이 제공하는 단순한 Table 엘러먼트를 로우 다중 선택, 서버 사이드 페이징 등의 필수 기능을 갖춘 그리드 위젯으로 탈바꿈시켜준다. Bootstrap v3를 지원하며 MIT License이다.


저작자 표시 비영리 동일 조건 변경 허락
신고

웹에서 Responsive Image(반응형 이미지) 구현하기

반응형 이미지는 어떻게 구현할까?


웹에서 고정된 크기를 가진 이미지를 데스크탑, 랩탑, 태블릿, 스마트폰 등 다양한 기기마다 최적화된 형태로 출력하려면 어떻게 해야할까? 해답은 간단하다. 반응형으로 출력하고 싶은 이미지의 img 엘러먼트에 style 애트리뷰트를 아래와 같이 부여하면 된다.


HTML에서는 아래와 같이 부여한다.

<img src="someImage.jpg" style="max-width: 100%; height: auto;">

CSS에서는 아래와 같이 부여한다.

img
{
  max-width: 100%;
  height: auto;
}


JavaScript에서는 아래와 같이 부여한다.

var img = document.getElementsByTagName("img");
vat i=0;
while (i < img.length) {
  img[i].setAttribute("style", "max-width: 100%; height: auto;");
  i++;
}


키워드: Responsive Image, 반응형 이미지



저작자 표시 비영리 동일 조건 변경 허락
신고