크로스 도메인 이슈

서문

요즘 마이크로 서비스가 대세입니다.
저는 요즘 Vuejs 를 이용한 Web app 을 만들려고 시도 중입니다.
이 웹앱을 마이크로 서비스로 만들려합니다. 이러한 경우에 만나는 문제가 바로 크로스 도메인 문제, CORS(Cross Origin Resource Sharing) 이슈입니다.

환경

현재 시스템은 localhost:8080 에 떠있는 RESTful API Server 에. localhost:8082에 떠있는 Web App 에서 http 요청을 해서 데이터를 가져오는 형태입니다.

문제점

간단한 SPA(Single Page Application) 어플을 만들 때, 이 웹 어플리케이션에 채워지는 데이터는 REST API 를 이용, 비동기 네트워크 통신으로 API 서버와 WEB APP의 서버가 다른 경우가 생깁니다.

이때 Web app 에서 ajax를 이용해서 REST API 를 호출하면 Browser console window 에서 이런 에러를 만나게 됩니다.

XMLHttpRequest cannot load http://localhost:8080/v1/. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8082' is therefore not allowed access.

원인

보안 상의 이유로, 브라우저들은 스크립트 내에서 초기화되는 cross-origin HTTP 요청을 제한하기 때문입니다.

해결책

간단합니다.
RESTful API서버의 RESPONSE HEADER 에 하나만 추가해주면 됩니다.

Access-Control-Allow-Origin: *

만약 특정 도메인만 허용하고 싶다면,

Access-Control-Allow-Origin: http://test.com, http://test2.com, …

이런 형태로 사용하시면 됩니다.

[tip] jquery input text에 숫자나 알파벳만 입력 받기

jquery 를 이용해서 html input tag에 숫자와 알파벳만 입력받도록 만든다.

웹 개발을 하다보면 인풋태그에 원하는 값만을 입력 받고 싶을 때가 있다.

현재 게임 운영툴을 개발하면서 숫자만 입력 받고 싶은 경우가 생겼다.

라이브러리를 찾아보았으나 한글이 입력되거나 특수문자가 입력되는 경우가 발생했다.

그래서 기존 라이브러리에 코드를 추가해서 한글이나 특수문자를 막고 숫자만 입력받는 로직을 만들었다.

필요하신분은 참고 하시길.

참고로 숫자입력만 허용하는 로직만 테스트된 상태며, 테스트는 구글 크롬에서만 하였다. (현재 운영툴이 크롬을 대상으로 개발하고 있기 때문)
익스플로러에서는 안됐던 듯 싶다.

사용법은 아래 링크타고 가서 원래 라이브러리파일을 다운 받으면 index.html에 상세히 있다.

https://github.com/johnantoni/jquery.alphanumeric

수정한 코드.

(function($){

	$.fn.alphanumeric = function(p) { 

		p = $.extend({
			ichars: "!@#$%^&*()+=[]\\\';,/{}|\":<>?~`.-_ ",
			nchars: "",
			allow: ""
		  }, p);	

		return this.each
			(
				function() 
				{

					if (p.nocaps) p.nchars += "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
					if (p.allcaps) p.nchars += "abcdefghijklmnopqrstuvwxyz";

					s = p.allow.split('');
					for ( i=0;i<s.length;i++) if (p.ichars.indexOf(s[i]) != -1) s[i] = "\\" + s[i];
					p.allow = s.join('|');

					var reg = new RegExp(p.allow,'gi');
					var ch = p.ichars + p.nchars;
					ch = ch.replace(reg,'');

					$(this).keydown
						(
							function (e)
								{

									if (!e.charCode) k = String.fromCharCode(e.which);
										else k = String.fromCharCode(e.charCode);
									// Korean filtering,  modified by ktg. 
									// if (k.charCodeAt(0) == 229) e.preventDefault();
									// exception not ascii code, and shift + number keys
									if (33 <= e.which && e.which <= 40) return;
									// 컨트롤 c,v,x,a는 허용
									if (e.ctrlKey && (k.match(/(c|v|x|a)/i) != null)) return;
									// 아스키코드 이외의 글자는 막기
									if (k.charCodeAt(0) > 127) e.preventDefault();
									// 특수문자 막기
									if (e.shiftKey&&k.match(/\d+/g)!=null) e.preventDefault();

									if (ch.indexOf(k) != -1) e.preventDefault();
									if (e.ctrlKey&&k=='v') e.preventDefault();

								}

						);

					$(this).bind('contextmenu',function () {return false});

				}
			);

	};

	$.fn.numeric = function(p) {

		var az = "abcdefghijklmnopqrstuvwxyz";
		az += az.toUpperCase();

		p = $.extend({
			nchars: az
		  }, p);	

		return this.each (function()
			{
				$(this).alphanumeric(p);
				// 복사 붙여넣기 방지 로직
				$(this).keyup
					(
						function (e)
							{
								var newVal = $(this).val().replace(/[^0-9\s]/gi,"");
								if (newVal != $(this).val()) {
									$(this).val( $(this).val().replace(/[^0-9\s]/gi,"") );
								}
							}
					);
			}
		);

	};

	$.fn.alpha = function(p) {

		var nm = "1234567890";

		p = $.extend({
			nchars: nm
		  }, p);	

		return this.each (function()
			{
				$(this).alphanumeric(p);
			}
		);

	};	

})(jQuery);