<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>run_dev_aiden</title>
        <link>https://velog.io/</link>
        <description>Hello!</description>
        <lastBuildDate>Sat, 31 Jul 2021 08:45:46 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>run_dev_aiden</title>
            <url>https://images.velog.io/images/run_dev_aiden/profile/dd3984ff-e870-488d-b0c9-79882be4ae12/social.jpeg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. run_dev_aiden. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/run_dev_aiden" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[JS] ES6 - Modules]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-ES6-Modules</link>
            <guid>https://velog.io/@run_dev_aiden/JS-ES6-Modules</guid>
            <pubDate>Sat, 31 Jul 2021 08:45:46 GMT</pubDate>
            <description><![CDATA[<h2 id="modules">Modules</h2>
<h3 id="import--export">Import &amp; Export</h3>
<p>Import 와 Export 는 자바스크립트의 코드를 모듈화 할수 있는 기능입니다.
다른 파일에 있는 자바스크립트를 특정 파일로 가져와 사용하는 의미 입니다.</p>
<pre><code>&lt;!-- index.html --&gt;
&lt;body&gt;
  &lt;script src=&quot;a.js&quot;&gt;&lt;/script&gt;
  &lt;script src=&quot;b.js&quot;&gt;&lt;/script&gt;
&lt;/body&gt;</code></pre><pre><code class="language-javascript">// a.js
var test = 10;
function func() {
  return test; 
}</code></pre>
<pre><code class="language-javascript">// b.js
var test = 20;</code></pre>
<p>위의 경우 유효범위가 전역으로 잡히기 때문에 값이 변하게 됩니다. 모듈화 패턴이나 라이브러리를 사용하여 해결 했지만 이제는 자바스크립트 언어 자체에서
모듈화를 지원합니다.</p>
<h3 id="export--import-사용법">Export &amp; Import 사용법</h3>
<pre><code class="language-javascript">export 변수, 함수</code></pre>
<p>다른 파일에서 가져다 쓸 변수나 함수 앞에 export 를 작성하면 Import 를 통해서 사용할 수 있습니다.</p>
<pre><code class="language-javascript">import { 불러올 변수, 함수 } from &#39;파일경로&#39;</code></pre>
<pre><code class="language-javascript">// app.js
import { test, func } from &#39;./test.js&#39;;
console.log( test ); // 10
console.log(func); // 30</code></pre>
<pre><code class="language-javascript">// test.js
var test = 10;
function func() {
   return 30;
}
export { test, func };</code></pre>
<p>웹팩과 같은 모듈 번들러를 이용하여 ES6 구문을 사용해야 합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] ES6 - 구조 분해 문법]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-ES6-%EA%B5%AC%EC%A1%B0-%EB%B6%84%ED%95%B4-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@run_dev_aiden/JS-ES6-%EA%B5%AC%EC%A1%B0-%EB%B6%84%ED%95%B4-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Sat, 31 Jul 2021 08:18:29 GMT</pubDate>
            <description><![CDATA[<h2 id="구조-분해-문법">구조 분해 문법</h2>
<p>객체와 배열의 구조를 분해 하여 표현하는 방식입니다.</p>
<pre><code class="language-javascript">var obj = {
  a: 1,
  b: 2,
  c: 3
}
var a = obj.a; // 1
var b = obj.b; // 2
var c = obj.c; // 3</code></pre>
<p>위처럼 객체의 프로퍼티 값을 가져오려면 위처럼 해야했습니다. </p>
<pre><code class="language-javascript">var obj = {
   a: 1,
   b: 2,
   c: 3
}
// 구조 분해 문법
var { a, b, c } = obj;
console.log(a); // 1
console.log(b); // 2
console.log(c); // 3</code></pre>
<p>이처럼 구조 분해 문법을 사용하면 코드가 훨씬 간결해집니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] ES6 - 템플릿 리터럴]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-ES6-%ED%85%9C%ED%94%8C%EB%A6%BF-%EB%A6%AC%ED%84%B0%EB%9F%B4</link>
            <guid>https://velog.io/@run_dev_aiden/JS-ES6-%ED%85%9C%ED%94%8C%EB%A6%BF-%EB%A6%AC%ED%84%B0%EB%9F%B4</guid>
            <pubDate>Sat, 31 Jul 2021 08:10:45 GMT</pubDate>
            <description><![CDATA[<h2 id="템플릿-리터럴">템플릿 리터럴</h2>
<p>템플릿 리터럴은 자바스크립트에서 문자열을 입력하는 방식입니다. 백틱(`)이라는 기호를 사용합니다.</p>
<pre><code class="language-javascript">var text = `Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry&#39;s standard dummy text ever since the 1500s, 
when an unknown printer took a galley of type and scrambled it to make a type specimen book.`</code></pre>
<p>보통은 줄바꿈을 할 때 <code>\n</code> 사용하는데 백틱(`)을 사용하면 엔터키가 적용이 됩니다.</p>
<pre><code class="language-javascript">var say = &quot;Hello&quot;;
var name = `${say} Aiden!`;
console.log(name); // Hello Aiden!</code></pre>
<p>백틱을 사용한다면 위처럼 문자열 안에서 변수 처리도 가능합니다. (연산처리도 가능)</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] ES6 - 스프레드 오퍼레이터]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-ES6-%EC%8A%A4%ED%94%84%EB%A0%88%EB%93%9C-%EC%98%A4%ED%8D%BC%EB%A0%88%EC%9D%B4%ED%84%B0</link>
            <guid>https://velog.io/@run_dev_aiden/JS-ES6-%EC%8A%A4%ED%94%84%EB%A0%88%EB%93%9C-%EC%98%A4%ED%8D%BC%EB%A0%88%EC%9D%B4%ED%84%B0</guid>
            <pubDate>Sat, 31 Jul 2021 07:46:51 GMT</pubDate>
            <description><![CDATA[<h2 id="스프레드-오퍼레이터spread-operator">스프레드 오퍼레이터(Spread Operator)</h2>
<p>스프레드 오퍼레이터는 펼침 연산자라고 합니다.
특정 객체 또는 배열 값을 다른 객체나 배열로 복제하거나 결합할 때 사용합니다.</p>
<pre><code class="language-javascript">// obj 객체 결합
const obj = {
   a: 1,
   b: 2,
}
const obj2 = {
   c: 3,
   d: 4
}
const newObj = {...obj, ...obj2};
console.log(newObj); // {a: 1, b: 2, c: 3, d: 4}

// arr 배열 복제
const arr = [1,2,3];
const arr2 = [4,5,6];
const newArr = [...arr, ...arr2];
console.log(newArr); // [1,2,3,4,5,6];</code></pre>
<h4 id="argument-활용-스프레드-연산">Argument 활용 스프레드 연산</h4>
<pre><code class="language-javascript">// 일반 함수 인자
function origin(obj) {
   // 파라미터 개수를 맞춰줘야함
   console.log(obj); // [1];
}
// 인자 스프레드 
function a(...obj) {
   console.log(obj); // [1,2,3,4,5]; 
}

function b(arg1, ...arg2) {
   console.log(arg1); // 1
   console.log(arg2); // [2,3,4,5];
}

origin(1,2,3,4,5);
a(1,2,3,4,5);
b(1,2,3,4,5);</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] ES6 - 향상된 객체 리터럴]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-%ED%96%A5%EC%83%81%EB%90%9C-%EA%B0%9D%EC%B2%B4-%EB%A6%AC%ED%84%B0%EB%9F%B4</link>
            <guid>https://velog.io/@run_dev_aiden/JS-%ED%96%A5%EC%83%81%EB%90%9C-%EA%B0%9D%EC%B2%B4-%EB%A6%AC%ED%84%B0%EB%9F%B4</guid>
            <pubDate>Sat, 31 Jul 2021 07:04:34 GMT</pubDate>
            <description><![CDATA[<h2 id="향상된-객체-리터럴">향상된 객체 리터럴</h2>
<p>향상된 객체 리터럴은 기존 자바스크립트에서 사용하던 객체 정의 방식을 개선한 문법입니다. </p>
<h5 id="기존-자바스크립트의-객체-정의-방식">기존 자바스크립트의 객체 정의 방식</h5>
<pre><code class="language-javascript">var obj = {
   // 속성: 값
   city: &#39;seoul&#39;,
   func: function() {
     console.log(&#39;Hello&#39;);
   }
};</code></pre>
<h4 id="축약-문법">축약 문법</h4>
<p>객체 정의 시에 속성과 값이 같이 있으면 축약이 가능합니다.</p>
<pre><code class="language-javascript">var city = &#39;seoul&#39;;
var obj = {
   // city: city,
   city
}
console.log(obj); // { city: &#39;seoul&#39; }</code></pre>
<h5 id="객체를-정의할-때-객체-속성에-함수를-연결하여-사용하는-경우">객체를 정의할 때 객체 속성에 함수를 연결하여 사용하는 경우</h5>
<pre><code class="language-javascript">var obj = {
   // 속성: 함수
   func: function() {
       console.log(&#39;Hello&#39;); 
   }
};
obj.func(); // Hello</code></pre>
<p>위와 같이 기존 함수 정의를 축약한다면 아래와 같이 할수 있습니다.</p>
<pre><code class="language-javascript">var obj = {
   func() {
      console.log(&#39;Hello&#39;); 
   }
};
obj.func(); // Hello</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] ES6 - Arrow Function]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-ES6-Arrow-Function</link>
            <guid>https://velog.io/@run_dev_aiden/JS-ES6-Arrow-Function</guid>
            <pubDate>Fri, 23 Jul 2021 11:45:27 GMT</pubDate>
            <description><![CDATA[<h2 id="arrow-function">Arrow Function</h2>
<p><code>Arrow Function</code> 은 ES6 의 새로운 함수 정의 방식입니다.</p>
<pre><code class="language-javascript">var a = function() {
    // 기존 함수 선언 방식 
}

var a = () =&gt; {
    // Arrow Function 방식
}
// or
var a = () =&gt; console.log(&#39;한줄 retrun&#39;);
var a = () =&gt; ( { &quot;객체&quot;: &quot;return&quot; } );

var a = arg =&gt; {
    // 매개변수가 하나일 경우 소괄호를 생략해도 됩니다.
}
var arr = [1,2,3];
var a = arr.filter(item =&gt; {
  // callback 함수 표현
});</code></pre>
<p>화살표 함수의 <code>this</code> 는 상위 스코프의 <code>this</code> 를 가리킵니다. 
이를 <code>lexical this</code> 라고 합니다.
이러한 특징으로 메소드 정의를 지양하는게 좋다고 합니다.</p>
<pre><code class="language-javascript">const person = {
   age: 10,
   say: ()=&gt; {
     console.log(&quot;Hello, I&#39;m&quot; + this.age); 
   }
}
person.say(); // Hello, I&#39;m undefined
// 이때 this 는 window 를 가르킵니다. 그러므로 오류를 발생시킵니다.</code></pre>
<p>다른 해결 방법으로 ES6의 함수 축약 표현이 있습니다.</p>
<pre><code class="language-javascript">const person = {
    age: 10,
    say() { // say: function() {} 와 같습니다.
    console.log(&quot;Hello, I&#39;m&quot; + this.age); 
    }
}
person.say(); // Hello, I&#39;m 10</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] ES6 문법]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-ES6-%EB%AC%B8%EB%B2%95-1am4yde6</link>
            <guid>https://velog.io/@run_dev_aiden/JS-ES6-%EB%AC%B8%EB%B2%95-1am4yde6</guid>
            <pubDate>Fri, 23 Jul 2021 11:04:06 GMT</pubDate>
            <description><![CDATA[<h2 id="es6-문법-살펴보기">ES6 문법 살펴보기</h2>
<blockquote>
</blockquote>
<p>const, let
Arrow Function 
향상된 객체 리터럴
스프레드 오퍼레이터 (Spread Operator)
템플릿 리터럴 
구조 분해 할당
Modules</p>
<p>ES6 문법에 대해 알아보기!</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] ES6 - let, const]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-ES6-%EB%AC%B8%EB%B2%95</link>
            <guid>https://velog.io/@run_dev_aiden/JS-ES6-%EB%AC%B8%EB%B2%95</guid>
            <pubDate>Fri, 23 Jul 2021 11:02:15 GMT</pubDate>
            <description><![CDATA[<h3 id="let-const">let, const</h3>
<h4 id="let">let</h4>
<p><code>let</code> 은 블록 유효 범위를 갖는 지역 변수를 선언하며, 선언과 동시에 임의의 값으로 초기화 할수 있다.</p>
<pre><code class="language-javascript">let a = 1;

if( a == 1 ){
  let a = 2;
  console.log(a); // output: 2
}
console.log(a); // output: 1</code></pre>
<p><code>let</code> 은 변수가 선언 된 블록안에서만 유효합니다.
<code>var</code> 블록 범위를 무시하고 선언 되므로 <code>let</code> 과 <code>var</code> 의 차이를 알수 있습니다.</p>
<h4 id="const">const</h4>
<p><code>const</code> 는 블록 범위의 상수를 선언합니다.
상수의 값을 재할당 할수 없고 재선언 할수도 없습니다.</p>
<pre><code class="language-javascript">const foo = 123;
foo = 345; // error: Uncaught TypeError: Assignment to constant variable.</code></pre>
<p><code>{}</code>,<code>[]</code> 오브젝트에서 값을 변경 할수 있고, 배열에서 값을 추가 할수 있습니다.</p>
<h4 id="for문에서의-유효범위">for문에서의 유효범위</h4>
<pre><code class="language-javascript">// for문에서 var 의 유효범위
var a = 1;
for(var a=0; a&lt;5; a++) {
   console.log(a); // 0 1 2 3 4 
}
console.log(a); // 5</code></pre>
<p>위에 코드에서 for문의 <code>{}</code> 안에 유효범위가 적용 되지 않기 때문에 마지막 콘솔의 값 5가 출력이 됩니다. 
이런 경우에는 작업중에 헷갈릴수 있기 때문에 <code>let</code> 으로 해결 할수 있습니다.</p>
<pre><code class="language-javascript">let a = 1;
for(let a=0; a&lt;5; a++) {
   console.log(a); // 0 1 2 3 4
}
console.log(a); // 1</code></pre>
<p><code>let</code> 을 사용하여 for문 안에 유효범위가 적용되었습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] Fullscreen API]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-Fullscreen-API</link>
            <guid>https://velog.io/@run_dev_aiden/JS-Fullscreen-API</guid>
            <pubDate>Tue, 13 Apr 2021 02:16:49 GMT</pubDate>
            <description><![CDATA[<h2 id="-fullscreen-mode">:) fullscreen mode</h2>
<p>특정 요소를 <code>Fullscreen mode</code> 로 표시하고 종료할 경우 사용 되는 메소드를 알아보겠습니다. </p>
<h3 id="methods">Methods</h3>
<h4 id="requestfullscreen">requestFullscreen</h4>
<pre><code class="language-javascript">Element.requestFullscreen()</code></pre>
<p>지정한 요소를 <code>Fullscreen mode</code> 로 설정하고 브라우져의 모든 UI요소와 다른 모든 애플리케이션을 화면에서 제거하도록 요구합니다.</p>
<h4 id="exitfullscreen">exitFullscreen</h4>
<pre><code class="language-javascript">Element.exitFullscreen()</code></pre>
<p>사용자가 <code>Fullscreen mode</code> 에서 창 모드로 다시 전환하도록 요청 할때 사용되는 메소드입니다.</p>
<hr>
<h3 id="properties">Properties</h3>
<p><code>document</code> 인터페이스는 <code>Full screen mode</code> 가 지원되고 <strong>사용가능</strong> 한지,
<strong>현재 활성화</strong> 되어 있는지, <strong>어떤 요소가 스크린을 사용</strong>하고 있는지 확인하는 속성을 제공합니다.</p>
<h4 id="fullscreenelement">fullscreenElement</h4>
<pre><code class="language-javascript">document.fullscreenElement</code></pre>
<p>DOM에서 현재 Fullscreen mode로 표시되는 요소(Element)를 알려줍니다. 
<code>null</code> 인 경우에 Fullscreen mode가 아닌 상태입니다.
배포시에 브라우져 환경에 맞게 <code>mozFullscreenElement</code>, <code>msFullscreenElement</code>, <code>webkitFullscreenElement</code> 확인해야 합니다.</p>
<h4 id="fullscreenenabled">fullscreenEnabled</h4>
<pre><code class="language-javascript">document.fullscreenEnabled</code></pre>
<p>이 속성은 <code>Full screen mode</code> 를 사용할 수 있는지 여부를 알려줍니다.
<code>Full screen mode</code> 를 사용할 수 없으면 false 를 반환합니다.</p>
<h3 id="event-handler">Event Handler</h3>
<p><code>Full screen mode</code> 켜고 끌 때나 변경하는 과정에서 오류가 발생하는 것을 감지하는데 사용할 수 있는 두 가지 이벤트를 알아보겠습니다.</p>
<h4 id="onfullscreenchange">onfullscreenchange</h4>
<pre><code class="language-javascript">document.onfullscreenchange = function(){
     console.log(&#39;Full screen mode가 변경될 때마다 출력됩니다.&#39;) 
}</code></pre>
<h4 id="onfullscreenerror">onfullscreenerror</h4>
<pre><code class="language-javascript">document.onfullscreenerror = function(){
      console.log(&#39;Full screen mode로 전환하거나 외부에서 전환을 시도하는 동안 오류가 발생하면 출력됩니다.&#39;
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 마우스 이벤트]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-%EB%A7%88%EC%9A%B0%EC%8A%A4-%EC%9D%B4%EB%B2%A4%ED%8A%B8</link>
            <guid>https://velog.io/@run_dev_aiden/JS-%EB%A7%88%EC%9A%B0%EC%8A%A4-%EC%9D%B4%EB%B2%A4%ED%8A%B8</guid>
            <pubDate>Fri, 09 Apr 2021 06:24:25 GMT</pubDate>
            <description><![CDATA[<h2 id="-마우스-이벤트">:) 마우스 이벤트</h2>
<p>마우스 이벤트에 대해서 알아보도록 하겠습니다.
마우스 이벤트는 마우스의 장치를 통해서만 생기는것이 아닌 핸드폰 테블릿 같은 다른 장치에서도 생깁니다.</p>
<h3 id="이벤트-종류">이벤트 종류</h3>
<p><code>mousedown / mouseup</code>
요소 위에서 마우스 왼쪽 버튼을 누를 때, 누르고 있다가 뗄 때 발생합니다.</p>
<p><code>mouseover / mouseout</code> 
마우스 커서가 요소 바깥에 있다가 요소 안으로 움직일 때,
커서가 요소 위에 있다가 요소 밖으로 움직일 때 발생합니다.</p>
<p><code>mousemove</code> 
마우스를 움직일 때 발생합니다.</p>
<p><code>contextmenu</code>
마우스 오른쪽 버튼을 눌렀을 때 발생합니다.</p>
<h4 id="clientxclienty-와-pagex-pagey">clientX,clientY 와 pageX, pageY</h4>
<p>클라이언트 좌표: clientX 와 clientY
페이지 좌표: pageX 와 pageY</p>
<p><code>클라이언트 좌표(client)</code>
웹문서를 기준으로 각각 왼쪽에서 얼마나 떨어져 있는지,
위에서 얼마나 떨어져 있는지를 나타내는데 페이지가 스크롤 되어도 변하지 않습니다.</p>
<p><code>페이지 좌표(page)</code> 
창 왼쪽 위를 기준으로 얼마나 떨어져 있는지를 나타내며 페이지를 스크롤 하면 값도 변합니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/2dd430cd-c045-41df-aa25-3a1c9a8b063c/mousepos.png" alt=""></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] 브라우져 창 사이즈와 스크롤]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%B8-%EC%B0%BD-%EC%82%AC%EC%9D%B4%EC%A6%88%EC%99%80-%EC%8A%A4%ED%81%AC%EB%A1%A4</link>
            <guid>https://velog.io/@run_dev_aiden/JS-%EB%B8%8C%EB%9D%BC%EC%9A%B0%EC%A0%B8-%EC%B0%BD-%EC%82%AC%EC%9D%B4%EC%A6%88%EC%99%80-%EC%8A%A4%ED%81%AC%EB%A1%A4</guid>
            <pubDate>Fri, 09 Apr 2021 01:44:00 GMT</pubDate>
            <description><![CDATA[<h2 id="브라우져-창-사이즈와-스크롤">브라우져 창 사이즈와 스크롤</h2>
<h3 id="브라우져-창의-너비와-높이">브라우져 창의 너비와 높이</h3>
<p>브라우져의 창 너비와 높이를 구하려면 
<code>document.documentElement.clientWidth</code> 와 <code>document.documentElement.clientHeight</code> 를 사용하여 값을 구합니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/7d5a6194-37f3-4efe-8b3e-4472f64e1e8a/%EC%BA%A1%EC%B2%98.PNG" alt=""></p>
<blockquote>
<p>window 객체와의 차이점</p>
</blockquote>
<p>브라우져의 <code>window</code> 객체에서도 <code>window.innerWidth</code> 와 <code>window.innerHeight</code> 를 사용하여 브라우져 창 너비와 높이 값을 구할 수 있습니다.</p>
<p><code>document.documentElement</code> 와 차이점은 스크롤바 공간의 값을 포함하는지 아닌지에 차이가 있습니다. </p>
<p><code>widnow</code> 스크롤바를 포함하여 창의 너비와 높이를 구하고 스크롤바 안쪽에 무언가를 위치 시킬 경우에 사용합니다. 
이 경우가 아닐 시에는 <code>documentElement.clientWidth/documentElement.clientHeight</code> 를 사용합니다.</p>
<h3 id="이외의-프로퍼티">이외의 프로퍼티</h3>
<h4 id="--scrollheightscrollwidth">- scrollHeight/scrollWidth</h4>
<p><code>scrollHeight/scrollWidth</code> 는 컨텐츠의 총 높이값을 구할 수 있습니다. 스크롤이 생겨 가려진 부분까지 값을 구할수 있습니다.
요소의 안쪽 여백은 포함하고 테두리와 바깥 여백, 수평스크롤바의 높이는 포함하지 않습니다.</p>
<p><code>( scrollHeight/scrollWidth 반환 값은 정수로 반올림 됨 )</code></p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/b7b54d21-28b0-4a04-8d09-186b6c1984a6/scrollHeight.png" alt=""></p>
<h4 id="--offsetwidthoffsetheight">- offsetWidth/offsetHeight</h4>
<p><code>offsetWidth/offsetHeight</code> 는 테두리, 패딩 스크롤바를 포함하여 요소의 css 너비를 픽셀 단위로 측정합니다.
<code>(요소가 숨겨져 있는 경우 0을 반환 합니다)</code></p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/811f0b02-6eb2-4b08-a74b-be0aa9a86038/dimensions-offset.png" alt=""></p>
<h4 id="--getboundingclientrect">- getBoundingClientRect()</h4>
<p><code>getBoundingClientRect()</code> 는 Dom 요소의 크기 및 뷰포트를 기준으로 한 위치에서
정보를 제공합니다.
x, y, width, height, top, right, bottom, left 등의 값을 구할수 있습니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/1e6250c0-9332-46a5-8eae-22e5eb23c398/element-box-diagram.png" alt=""></p>
<h3 id="스크롤-정보-얻기">스크롤 정보 얻기</h3>
<p><code>document.body.scorllLeft/document.body.scrollTop</code><br>Dom 요소의 현재 스크롤 상태는 <code>scrollLeft</code> 와 <code>scrollTop</code> 프로퍼티를 사용하여 구할 수 있습니다.
브라우져의 호환성을 위해서는 
<code>window.pageYOffset/window.pageXOffset</code> 를 사용해야 합니다.
기능의 동일합니다.</p>
<p><code>scrollBy(x,y)</code> 는 현재 스크롤 위치를 기준으로 상대적으로 조정합니다.
예를들면, <code>scrollBy(0,10)</code> 를 사용 한다면 현재 기준의 스크롤에서 10px 아래로 내려갑니다.</p>
<p><code>scrollTo(pageX,pageY)</code> 는 <code>scrollBy()</code> 와는 달리 절대좌표를 기준으로 페이지의 스크롤 상태를 변경합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[vue 설치 및 eslint & prettier]]></title>
            <link>https://velog.io/@run_dev_aiden/vue-%EC%84%A4%EC%B9%98</link>
            <guid>https://velog.io/@run_dev_aiden/vue-%EC%84%A4%EC%B9%98</guid>
            <pubDate>Wed, 24 Mar 2021 12:04:20 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/run_dev_aiden/post/d5d9a2fe-b653-4a70-9f1c-7b8e5ca9d2f5/eslint_prettier.png" alt=""></p>
<h4 id="노드버전-변경하기">노드버전 변경하기</h4>
<pre><code class="language-javascript">nvm install xx.12.0</code></pre>
<h4 id="vue-cli-설치">vue cli 설치</h4>
<pre><code class="language-javascript">npm install -g @vue/cli
// version 확인
vue --version
// create
vue create [사용자임의 폴더명]</code></pre>
<h4 id="화면-error-overlay-없애기">화면 error overlay 없애기</h4>
<p>vue.config.js 파일을 만들어 주고 아래의 코드를 작성해주면 됩니다.</p>
<pre><code class="language-javascript">// vue.config.js
module.exports = {
    devServer: {
         overlay: false 
    }
}</code></pre>
<h4 id="eslint">eslint</h4>
<h5 id="설치하기">설치하기</h5>
<pre><code class="language-javascript">npm i eslint eslint-config-prettier eslint-plugin-prettier eslint-plugin-vue --save-dev</code></pre>
<p>eslintrc.js를 추가합니다</p>
<pre><code class="language-javascript">// .eslintrc.js
module.exports ={
     //....
      rules: {
         &quot;no-console&quot;: process.env.NODE_ENV === &quot;production&quot; ? &quot;error&quot; : &quot;off&quot;
    }
}</code></pre>
<p>rules에 <strong>no-console</strong> 은 개발중에 페이지 내에 콘솔이 있는경우 오류를 발생 시킵니다.</p>
<h4 id="prettier">prettier</h4>
<p>eslint 안으로 들어가야합니다
rules와 충돌이 나기 때문입니다.</p>
<pre><code class="language-javascript">// .eslintrc.js
module.exports ={
     //....
      rules: {
         &quot;no-console&quot;: process.env.NODE_ENV === &quot;production&quot; ? &quot;error&quot; : &quot;off&quot;,
          &quot;prettier/prettier&quot;: [&#39;error&#39;,{
            singleQuote: true,
            semi: true,
            useTabs: true,
            tabWidth: 2,
            trailingComma: &#39;all&#39;,
            printWidth: 80,
            bracketSpacing: true,
            arrowParens: &#39;avoid&#39;,
      }]
    }
}
// vscode 설정 settings.json 
{
     &quot;editor.formatOnSave&quot;: true,
    &quot;editor.formatOnType&quot;: true,
    &quot;eslint.validate&quot;: [
        { &quot;language&quot;: &quot;vue&quot;, &quot;autoFix&quot;: true }, //vue 체크
        { &quot;language&quot;: &quot;javascript&quot;, &quot;autoFix&quot;: true }, //자바스크립트 체크
        { &quot;language&quot;: &quot;html&quot;, &quot;autoFix&quot;: true } //HTML 체크 &lt;div&gt;&lt;/div&gt; -&gt; &lt;div /&gt;
        { &quot;language&quot;: &quot;react&quot;, &quot;autoFix&quot;: true}
      ],
}</code></pre>
<p>위 코드는 작업중에 코드를 작성하고 저장할 경우에 자동으로 코드를 정리해줍니다.
validate는 autofix를 통해 설정된 language를 체크 하고 자동으로 변경 해줍니다.</p>
<h4 id="절대경로-설정하기">절대경로 설정하기</h4>
<p>먼저 <strong>jsconfig.json</strong> 파일을 생성합니다.
이 파일은 vscode 내부의 기능 설정을 위한 파일입니다.</p>
<pre><code class="language-javascript">{
  &quot;compilerOptions&quot;: {
    &quot;baseUrl&quot;: &quot;.&quot;,
    &quot;paths&quot;: {
      &quot;~/*&quot;: [
        &quot;./*&quot;
      ],
      &quot;@/*&quot;: [
        &quot;./src/*&quot;
      ],
    }
  },
  // 제외하는 목록
  &quot;exclude&quot;: [
    &quot;node_modules&quot;,
    &quot;dist&quot;
  ]
}</code></pre>
<p>절대경로를 설정하는 이유는 컴포넌트가 많아질 경우 경로를 찾기가 번거롭기 때문입니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[web] 웹 서비스 개발 절차]]></title>
            <link>https://velog.io/@run_dev_aiden/web-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4-%EA%B0%9C%EB%B0%9C-%EC%A0%88%EC%B0%A8</link>
            <guid>https://velog.io/@run_dev_aiden/web-%EC%9B%B9-%EC%84%9C%EB%B9%84%EC%8A%A4-%EA%B0%9C%EB%B0%9C-%EC%A0%88%EC%B0%A8</guid>
            <pubDate>Wed, 24 Mar 2021 11:40:34 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/run_dev_aiden/post/3810d896-ec0e-48dd-b654-f6955545e871/Web-Service-Provider.jpeg" alt=""></p>
<h3 id="웹서비스의-개발-절차">웹서비스의 개발 절차</h3>
<p>1) 요구사항 
2) 서비스 기획
3) UI, UX 상세 설계
4) GUI 디자인
5) 퍼블리싱
6) 백엔드 API 개발
7) 프론트엔드 개발
8) QA</p>
<h4 id="프론트엔드-개발자-역할">프론트엔드 개발자 역할</h4>
<ul>
<li>화면단 코드를 작성합니다. </li>
<li>기획, 디자인, 퍼블리싱, 백엔드 개발자와 소통</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] #1 Javascript]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-1-Javascript</link>
            <guid>https://velog.io/@run_dev_aiden/JS-1-Javascript</guid>
            <pubDate>Mon, 28 Sep 2020 12:24:33 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/run_dev_aiden/post/12bc8ca6-069c-4437-b88e-4f44aad16e72/js.png" alt=""></p>
<h2 id="-javascript-란">:) Javascript 란?</h2>
<p>자바스크립트는 웹페이지에 생동감을 붙여 넣기 위해 만들어진 프로그래밍 언어입니다.
스크립트는 웹페이지의 HTML 안에 작성 할 수 있는데, 웹 페이지를 불러 올 때 스크립트가 자동으로 실행 됩니다.
어떤 사람들은 Java(자바) 와 혼동을 하는데 Javascript와 다른 언어 입니다.</p>
<p><code>자바스크립트</code>는 브라우저 뿐만 아니라 서버에서도 실행 할 수 있습니다.
이외에 <code>자바스크립트 엔진</code> 이라 불리는 특별한 프로그램이 들어 있는 모든 디바이스에서도 동작 합니다.</p>
<p>브라우저에는 <code>자바스크립트 가상 머신</code> 이라 불리는 엔진이 내장 되어 있습니다.</p>
<p><strong>엔진의 종류</strong></p>
<ul>
<li><code>V8</code> - 크롬(Chrome)과 오페라(Opera) 에서 쓰입니다.</li>
<li><code>SpiderMonkey</code> - 파이어폭스(Firefox) 에서 쓰입니다.</li>
<li>IE는 마이크로 소프트에서 지원을 종료한다고 발표하였습니다.</li>
</ul>
<p><strong>엔진의 기본 동작 원리</strong></p>
<ol>
<li>엔진(브라우져 내장엔진)이 스크립트를 읽습니다(파싱)</li>
<li>읽어 들인 스크립트를 기계어로 전환합니다(컴파일).</li>
<li>기계어로 전환된 코드가 실행됩니다. 기계어로 전환되었기 때문에 실행 속도가 빠릅니다.</li>
</ol>
<p>엔진은 프로세스 각 단계마다 최적화를 진행합니다. 또한 컴파일이 끝나고 실행 중인 코드를 감시하고, 이 코드로 흘러가는 데이터를 분석하고 분석 결과를 토대로 기계어로 전환된 코드를 다시 최적화 하기도 합니다. 이런 과정으로 스크립트 실행 속도는 더욱 더 빨라집니다.</p>
<h3 id="브라우저에서-할-수-있는-일">브라우저에서 할 수 있는 일</h3>
<ul>
<li>페이지에 새로운 HTML을 추가하거나 기존 HTML이나 Style을 수정</li>
<li>마우스 클릭이나 포인터의 움직임, 키보드 키 눌림 등과 같은 사용자 행동에 반응하기</li>
<li>네트워크를 통해 원격 서버에 요청을 보내거나, 파일 다운로드, 업로드하기(ajax, comet 같은 기술사용)</li>
<li>쿠키를 가져오거나 설정, 사용자에게 질문을 건네거나 메세지 보여주기</li>
<li>클라이언트 측에 데이터 저장하기(로컬스토리지)</li>
</ul>
<h3 id="브라우저에서-할-수-없는-일">브라우저에서 할 수 없는 일</h3>
<p><strong>제약사항</strong></p>
<ul>
<li><p>웹페이지 내 스크립트는 디스크에 저장된 임의의 파일을 읽거나 쓰고, 복사하거나 실행할 때 제약을 받을수 있습니다. 운영체제가 지원하는 기능을 브라우저가 직접 쓰지 못하게 막혀있기 때문입니다.</p>
</li>
<li><p>모던 브라우저를 사용하면 파일을 다룰 순 있습니다. 하지만 접근은 제한되어 있습니다. 
사용자가 브라우저 창에 파일을 &#39;끌어다 두거나&#39; <code>&lt;input&gt;</code> 태그를 통해 파일을 선택할 때와 같이 특정 상황에서만 파일 접근을 허용합니다.</p>
</li>
<li><p>카메라나 마이크 같은 디바이스와 상호 작용하려면 사용자의 명시적인 허가가 있어야 합니다. 자바스크립트가 활성화된 페이지라도 사용자 몰래 웹 카메라를 작동 시켜 수집한 정보를 국가안보국과 같은 곳에 몰래 전송할 수 없습니다.</p>
</li>
<li><p>브라우저 내에 탭과 창은 대게 서로의 정보를 알 수 없습니다. 하지만 자바스크립트를 사용해 한 창에서 다른 창을 열 때는 예외가 적용됩니다. 하지만 이 경우에도 도메인이나 프로토콜, 포트가 다르다면 페이지에 접근할 수 없습니다. 이런 제약사항을 <code>동일 출처 정책(Same Origin Policy)</code> 라 부릅니다. 이 정책을 피하려면 두 페이지는 데이터 교환에 동의해야 하고, 동의와 관련된 특수한 자바스크립트 코드를 포함하고 있어야 합니다.
<code>http://site.com</code> 에서 받아온 페이지가 <code>http://gmail.com</code>에서 받아온 페이지 상의 정보에 접근해 중요한 개인정보를 훔치는걸 막기 위함입니다. </p>
</li>
<li><p>자바스크립트를 이용하면 페이지를 생성한 서버와 쉽게 정보를 주고 받을 수 있습니다. 하지만 타 사이트나 도메인에서 데이터를 받아오는건 불가능 합니다. 가능하다 할지라도 원격 서버에서 명확히 승인을 해줘야 합니다(HTTP 헤더 등을 이용), CORS 관련.</p>
</li>
</ul>
<h3 id="자바스크립트의-강점">자바스크립트의 강점</h3>
<ul>
<li>Html/Css와 완전히 통합할 수 있음</li>
<li>간단한 일은 간단하게 처리 가능</li>
<li>모든 주요 브라우저에서 지원하고, 기본 언어로 사용됨</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JS] selection-range]]></title>
            <link>https://velog.io/@run_dev_aiden/JS-selection-range</link>
            <guid>https://velog.io/@run_dev_aiden/JS-selection-range</guid>
            <pubDate>Tue, 15 Sep 2020 09:34:47 GMT</pubDate>
            <description><![CDATA[<h2 id="selection-range">Selection-range</h2>
<h3 id="선택-및-범위">선택 및 범위</h3>
<p>기존 선택을 가져오고 전체 또는 부분적으로 선택하고 취소하고, 문서에서 선택한 부분을 제거하고 태그로 래핑 하는 등의 작업을 수행할 수 있습니다.</p>
<h3 id="range">Range</h3>
<p>선택의 기본 개념 Range: 기본적으로 한 쌍의 경계지점이며 범위 시작 및 범위 끝입니다.
각 포인트는 시작부터 상대적 오프셋이 있는 상위 DOM 노드로 표시됩니다. 
부모노드가 요소 노드이면 오프셋은 자식 번호,
텍스트 노드의 겨우 텍스트에서 위치합니다.</p>
<p><strong>Range 속성</strong></p>
<ul>
<li><code>Range.collpased</code>
Range의 시작점과 끝점이 동일한지 여부</li>
<li><code>Range.commonAncestorContainer</code>
시작 컨테이너와 끝 컨테이너를 포함하고 있는 상위 노드</li>
<li><code>Range.endContainer</code>
Range가 끝나는 지점의 끝 컨테이너 노드</li>
<li><code>Range.endOffset</code>
endContainer 노드에서 끝 지점의 오프셋</li>
<li><code>Range.startContainer</code>
Range가 시작하는 지점의 컨테이너 노드</li>
<li><code>RangestartOffset</code>
startContainer 노드에서 시작 지점의 오프셋</li>
</ul>
<p>Range를 생성합니다.</p>
<pre><code class="language-javscript">let range = new Range();</code></pre>
<p>사용할 선택경계를 설정 할 수 있습니다.
<code>range.setStart(node, offset)</code> 및 <code>range.setEnd(node, offset)</code> </p>
<p>아래의 코드로 예시를 알아보겠습니다.</p>
<pre><code class="language-html">&lt;div id=&quot;rangeTest&quot;&gt;
  Example: &lt;i&gt;Italic&lt;i&gt; and &lt;b&gt;bold&gt;&lt;/b&gt;
&lt;/div&gt;</code></pre>
<p>부모노드가 요소노드이기 때문에
<code>Example:</code> : 0
<code>&lt;i&gt;Italic&lt;/i&gt;</code>: 1
<code>and</code> : 2
<code>&lt;b&gt;bold&lt;/b&gt;</code> : 3
로 자식번호가 구성 됩니다.</p>
<p>아래의 이미지 처럼
<code>range.setStart(rangeTest,0)</code> 범위 시작을 설정하고,
<code>range.setEnd(rangeTest,2)</code> 범위 끝을 설정합니다.
*setEnd는 끝이 포함되지 않는 특징이 있습니다. 
아래의 이미지로 결과를 확인 할 수 있습니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/8d8de5bf-5e9d-44f5-a02e-d7913edb7eb1/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.43.55.png" alt=""></p>
<p>이번에는 클릭하여 직접 입력한 범위 만큼 Range 를 선택해 보겠습니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/67ee4a69-0e10-4f77-a27b-c8a0de546725/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%207.05.16.png" alt=""></p>
<p>위의 코드에서 <code>&lt;input type=&quot;number&quot;&gt;</code> 를 통해 범위 설정을 해주고 이벤트를 주기위해 <code>&lt;button&gt;</code> 태그를 추가하 였습니다. <code>range.setStart(rangeTest, start.value)</code> 를 보시면 시작 범위 값을 넣어주고, <code>range.setEnd(rangeTest, end.value)</code> 에서 범위의 끝을 설정해주고 기존 선택 된 Range를 지우기 위해 <code>removeAllRange()</code> 로 초기화를 해주고 다시 Range를 추가 해주는것을 확인 할 수 있습니다.</p>
<p>텍스트 노드를 부분적으로 선택도 가능합니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/cfc34031-b86e-4025-b536-56d471669ec3/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%207.45.14.png" alt=""> </p>
<p>위의 코드에서 <code>range.setStart(rangeTest.firstChild, 2)</code> 는 rangeTest의 첫번째 자식요소에서 2로 설정 되어져 있습니다. 그러므로 <code>Example:</code> 에서 <code>a</code> 부터 시작 offset 입니다. <code>range.setEnd(rangeTest.querySelector(&#39;b&#39;).firstChild, 3)</code> 은 rangeTest에서 b 태그를 선택해 첫번째 자식의 끝 offset은 3으로 설정 되어 있습니다. 
<code>&lt;b&gt;</code> 자식 노드 첫번째는 <code>bold</code> 이고 offset이 3이어서 <code>bol</code> 까지 Range가 추가 되는것을 확인할 수 있습니다.</p>
<h3 id="선택-이벤트">선택 이벤트</h3>
<p>선택을 추적 하는 이벤트를 알아 보겠습니다.
<code>elem.onselectstart</code> 는 선택이 시작될 때 이벤트 발생하고
<code>elem.onselectionchange</code> 는 선택이 변경될 때마다 이벤트 발생합니다.
*이 핸들러는 document에서만 설정할 수 있습니다.</p>
<p><strong>Selction</strong></p>
<ul>
<li>anchor
Selection의 시작점.
마우스로 드래그 해서 선택했을 경우에 anchor 는 최초에 마우스가 클릭 된 지점입니다.
사용자가 마우스나 키보드로 Selection을 수정해도 anchor는 변경되지 않습니다.
텍스트를 위/아래로 드래그 했을 때 고정된 지점이 anchor 입니다.</li>
<li>focus
Selection의 끝점.
마우스로 Selection을 만들었을 경우에 마우스를 뗀 곳이 Selection의 focus 지점입니다.</li>
<li>Range
문서에 인접한 부분.
일반적으로 사용자는 한 개의 Range만 선택할 수 있지만, Ctrl 등의 키로 Multi Range를 사용할 수 있습니다. Range는 객체로 리턴됩니다 </li>
</ul>
<p><strong>Selection 의 속성</strong></p>
<ul>
<li><code>Selection.anchorNode</code>
시작노드</li>
<li><code>Selection.anchorOffset</code>
시작노드에서 anchor 오프셋.
anchorNode가 텍스트 노드면 anchor 이전에 문자열 개수고, 
anchorNode가 엘리먼트일 경우엔 anchor 보다 앞에 있는 자식 노드의 개수를 의미합니다.</li>
<li><code>Selection.focusNode</code>
끝 노드</li>
<li><code>Selection.focusOffset</code>
끝 노드에서 focus의 오프셋.
focusNode가 텍스트 노드면 focus 이전에 문자열 개수고,
focusNode가 엘리먼트일 경우엔 focus보다 앞에 있는 자식 노드의 개수를 의미합니다.</li>
<li><code>Selection.isCollapsed</code>
Selection의 시작지점과 끝지점이 동일한지의 여부</li>
<li><code>Selection.rangeCount</code>
Selection 내의 Range 개수</li>
</ul>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/e8478265-b8b5-43f1-9b2f-fc9f4c4d7219/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-15%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.58.27.png" alt=""></p>
<p>위 코드에서는 <code>onselectionchange</code> 메소드를 사용하여 선택시 <code>from</code> 의 value를 <code>anchorNode</code> 가 있을 경우에 data를 가져와 주고 <code>anchorOffset</code> 을 설정한걸 볼수 있습니다. 마찬가지로 <code>to</code> 의 value도 같습니다. 
이미지에서 드래그 된 텍스트와 <code>input</code> 에 각각의 결과를 확인할 수 있습니다.</p>
<h3 id="폼-요소에서-선택">폼 요소에서 선택</h3>
<p>input 및 textarea 같은 폼 요소에서 selection 하는 경우를 알아보겠습니다.
<strong>속성</strong></p>
<ul>
<li><code>input.selectionStart</code> 
Selection 시작 위치</li>
<li><code>input.selectionEnd</code>
Selection 끝 위치</li>
<li><code>input.selectionDirection</code>
선택방향은 앞으로, 뒤로, 또는 없음(더블클릭선택) 으로 구분됩니다. </li>
</ul>
<p><strong>이벤트</strong></p>
<ul>
<li><code>input.onselect</code>
selection 시 트리거 됩니다.</li>
</ul>
<p><strong>행동양식</strong></p>
<ul>
<li><code>input.select()</code>
텍스트 컨트롤의 모든 항목을 선택합니다.</li>
<li><code>input.setSelectionRange(start, end, [direction])</code>
지정된 방향으로 start 위치에서 end 까지 선택범위를 변경합니다.</li>
<li><code>input.setRangeText(replacement, [start], [end], [selectionModel])</code>
텍스트 범위를 새 텍스트로 바꿉니다.<ul>
<li><code>select</code> : 새로 삽입 된 텍스트가 선택 됩니다.</li>
<li><code>start</code> : 선택 범위는 삽입 된 텍스트 바로 전에 축소 됩니다.</li>
<li><code>end</code> : 선택 범위는 삽입 된 텍스트 바로 뒤에 축소 됩니다.</li>
<li><code>preserve</code> : 선택을 보존합니다. 기본값</li>
</ul>
</li>
</ul>
<h4 id="선택-수정">선택 수정</h4>
<p>선택 내용을 수정하려면 <code>input.setRangeText()</code> 메소드를 사용하면 됩니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/6cd6a9bc-4631-4cd8-9fbe-a56c0da7daec/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-16%20%E1%84%8B%E1%85%A9%E1%84%8C%E1%85%A5%E1%86%AB%2012.38.02.png" alt=""></p>
<p>위의 코드에서 <code>area</code> 의 시작과끝이 같을 경우에는 return 을 해주고 선택 했을 경우 <code>selectionStart</code> 와 <code>selectionEnd</code> 를 사용하여 선택범위 값을 변수에 할당 합니다. 그후 <code>setRangeText()</code> 를 사용하여 텍스트를 수정해 줍니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MongoDB 연결하기(2)]]></title>
            <link>https://velog.io/@run_dev_aiden/MongoDB-%EC%97%B0%EA%B2%B02</link>
            <guid>https://velog.io/@run_dev_aiden/MongoDB-%EC%97%B0%EA%B2%B02</guid>
            <pubDate>Wed, 09 Sep 2020 14:36:28 GMT</pubDate>
            <description><![CDATA[<h2 id="schema">Schema</h2>
<p>Schema 는 컴퓨터 프로그래밍에서 데이터베이스의 조직이나 구조를 의미합니다. 데이터 모델링은 결국 하나의 스키마에 이르게 됩니다.
즉 DB내에 어떤 구조로 데이터에 저장되는가를 나타내는 데이터베이스 구조를 Schema라고 합니다.</p>
<h3 id="schema-만들기">Schema 만들기</h3>
<p>사용자의 운동 스케쥴을 만들기 위해
먼저 routes 폴더를 만들고 users.js 와 exercises.js를 생성합니다.
schema를 위해 models 폴더를 만들고 user.model.js 와 exercise.model.js 도 만들어 줍니다.</p>
<p>아래 server.js 코드에서 <code>exerciseRouter</code> 와 <code>userRouter</code> 를 불러와 app.use()를 사용해 경로 지정 후 router 파일을 설정합니다.</p>
<pre><code class="language-javascript">//server.js
const express = require(&quot;express&quot;); // express 미들웨어
const cors = require(&quot;cors&quot;); // cors 미들웨어
const mongoose = require(&quot;mongoose&quot;); // mongoose
require(&quot;dotenv&quot;).config(); // 환경변수를 위한 dotenv

const app = express();
const port = process.env.PORT || 5000;

app.use(cors());
app.use(express.json());

const uri = process.env.ATLAS_URI; // mongoDB Connect 정보
mongoose.connect(uri, {
  useNewUrlParser: true,
  useCreateIndex: true,
  useUnifiedTopology: true,
});
const connection = mongoose.connection;
connection.once(&quot;open&quot;, () =&gt; {
  console.log(&quot;MongoDB database connection succes&quot;);
});

const exercisesRouter = require(&quot;./routes/exercises&quot;);
const userRouter = require(&quot;./routes/users&quot;);

app.use(&quot;/exercises&quot;, exercisesRouter);
app.use(&quot;/users&quot;, userRouter);

app.listen(port, () =&gt; {
  console.log(`Server is running on port ${port}`);
});
</code></pre>
<p>users.js 코드에서 Router 모듈을 설정하고 user.model.js를 불러옵니다.
model에서 Schema는 mongoose 모듈을 불러와 mongoose.Schema 를 인스턴스화 하여 새로운 userSchema의 필드를 설정 해줍니다.</p>
<p>필드에는 다양한 속성을 설정할 수 있습니다.</p>
<ul>
<li>required: 필수 입력입니다.</li>
<li>unique: 다른 행과 중복되면 안됩니다.</li>
<li>trim: 공백을 제거합니다.(문자열 타입에 사용)</li>
<li>default: 문서가 생성되면 기본값으로 저장됩니다.</li>
<li>lowercase: 대문자를 소문자로 저장합니다(문자열 타입)</li>
<li>match: 정규식으로 저장하려는 값과 비교합니다.</li>
<li>validate: 함수로 조건을 만듭니다.</li>
<li>set: 값을 입력할 때 함수로 조건을 만듭니다.</li>
<li>get: 값을 출력할 때 함수로 조건을 만듭니다.</li>
<li>ref: 해당하는 모델을 참조할 때 사용합니다.</li>
</ul>
<pre><code class="language-javascript">// user.model.js
const mongoose = require(&quot;mongoose&quot;); // mongoose 모듈 불러오기
const Schema = mongoose.Schema; 
const userSchema = new Schema(
  {
    username: {
      type: String,
      required: true,
      unique: true,
      trim: true,
      minlength: 3,
    },
    age: {
      type: Number,
      required: true,
      unique: true,
      trim: true,
      maxlength: 3,
    },
  },
  { timestamps: true }
);

const User = mongoose.model(&quot;User&quot;, userSchema);
module.exports = User;</code></pre>
<p>users 는 조회, 추가로 구성되어 있습니다.</p>
<pre><code class="language-javascript">// users.js
const router = require(&quot;express&quot;).Router();
let User = require(&quot;../models/user.model&quot;);

router.get(&quot;/&quot;, (req, res) =&gt; {
  User.find()
    .then((users) =&gt; res.json(users))
    .catch((err) =&gt; res.status(400).json(&quot;Error: &quot; + err));
});

router.post(&quot;/add&quot;, (req, res) =&gt; {
  const username = req.body.username;
  const newUser = new User({ username });

  newUser
    .save()
    .then(() =&gt; res.json(&quot;User added!&quot;))
    .catch((err) =&gt; res.status(400).json(&quot;Error: &quot; + err));
});
module.exports = router;</code></pre>
<p>exercises 도 app.use()를 사용하여 user 와 같이 route 설정을 해주고 Schema 모델을 만들어줍니다.</p>
<pre><code class="language-javascript">// exercise.model.js
const mongoose = require(&quot;mongoose&quot;);
const Schema = mongoose.Schema;

const exerciseSchema = new Schema(
  {
    username: { type: String, required: true },
    description: { type: String, required: true },
    duration: { type: Number, required: true },
    date: { type: Date, required: true },
  },
  {
    timestamps: true,
  }
);

const Exercise = mongoose.model(&quot;Exercise&quot;, exerciseSchema);

module.exports = Exercise;</code></pre>
<p>exercises 는 데이터 조회, 추가, 해당유저 조회, 해당유저 삭제로 구성되어 있습니다.</p>
<pre><code class="language-javascript">// exercises.js
const router = require(&quot;express&quot;).Router();
const Exercises = require(&quot;../models/exercise.model&quot;);

router.get(&quot;/&quot;, (req, res) =&gt; {
  Exercises.find()
    .then((exercise) =&gt; res.json(exercise))
    .catch((err) =&gt; res.status(400).json(&quot;ERROR: &quot; + err));
});

router.post(&quot;/add&quot;, (req, res) =&gt; {
  const username = req.body.username;
  const description = req.body.description;
  const duration = Number(req.body.duration);
  const date = Date.parse(req.body.date);

  const newExercise = new Exercises({
    username,
    description,
    duration,
    date,
  });

  newExercise
    .save()
    .then(() =&gt; res.json(&quot;Exercise added!&quot;))
    .catch((err) =&gt; res.status(400).json(&quot;ERROR :&quot; + err));
});

router.get(&quot;/:id&quot;, (req, res) =&gt; {
  Exercises.findById(req.params.id)
    .then((exer) =&gt; res.json(exer))
    .catch((err) =&gt; res.status(400).json(&quot;ERROR: &quot; + err));
});

router.delete(&quot;/:id&quot;, (req, res) =&gt; {
  Exercises.findByIdAndDelete(req.params.id)
    .then(() =&gt; res.json(&quot;Exercise deleted&quot;))
    .catch((err) =&gt; res.status(400).json(&quot;ERROR :&quot; + err));
});

router.put(&quot;/update/:id&quot;, (req, res) =&gt; {
  Exercises.findById(req.params.id)
    .then((exercise) =&gt; {
      exercise.username = req.body.username;
      exercise.description = req.body.description;
      exercise.duration = Number(req.body.duration);
      exercise.date = Date.parse(req.body.date);
      exercise
        .save()
        .then(() =&gt; res.json(&quot;Updated!&quot;))
        .catch((err) =&gt; res.status(400).json(&quot;ERROR: &quot; + err));
    })
    .catch((err) =&gt; res.status(400).json(&quot;ERROR: &quot; + err));
});

module.exports = router;</code></pre>
<p>이제 Postman을 이용해서 데이터 각 요청에 대해 어떻게 동작 하는지 알아보겠습니다.</p>
<p>아래의 이미지는 <code>http://localhost:5000/user/add</code>에 POST 로 JSON 형태로 요청하는 화면입니다.
하단에 결과 모습으로 User added! 미리 정해 놓은 요청 성공의 문구를 확인 할 수 있습니다. </p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/9ede395d-8ccd-466c-af17-4bae0438371f/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-10%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.39.50.png" alt=""></p>
<p>정말로 잘 저장 되었는지 확인 해보겠습니다.
<code>http://localhost:5000/users/</code> 에 GET 으로 요청을 보내면 데이터가 잘 추가 된걸 확인 할수 있습니다.
<img src="https://images.velog.io/images/run_dev_aiden/post/a1b34de7-e730-438c-8e12-7e86a9e6090a/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-10%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.40.57.png" alt=""></p>
<p>이어서 exercises도 시도해 보겠습니다.
<code>http://localhost:5000/exercises/add</code> 에 POST로 설정하고
필드에 맞게 username, description, duration, date 를 JSON 형태로 보내줍니다.
하단에 Exercise added! 문구로 저장 된 걸 확인 할수 있습니다.
<img src="https://images.velog.io/images/run_dev_aiden/post/f1b04b56-7d97-4879-b19c-89e14ccc16b7/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-10%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.50.13.png" alt=""></p>
<p>마찬가지로 <code>http://localhost:5000/exercises/</code> 에 GET으로 요청을 보내 실제로 잘 적응 됬는지 데이터를 확인 할 수 있습니다.
<img src="https://images.velog.io/images/run_dev_aiden/post/535a9ebe-578c-4931-b5fa-0bac74b6ea67/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-10%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.54.43.png" alt=""></p>
<p>이제 MongoDB Cluster에 Collection에서 상호작용 된 형태를 확인 할수 있습니다. 요청으로 추가 해주었던 데이터들이 MongoDB에 보기 좋게 저장 되어있는걸 확인 할수 있습니다. 
<img src="https://images.velog.io/images/run_dev_aiden/post/24f30384-9473-4fcb-9516-df3998c8d6cd/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-10%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.57.41.png" alt=""></p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/df64ce3c-6093-4f11-ba61-22f098fd2135/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-10%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.57.54.png" alt=""></p>
<p>데이터를 수정하기 위해서는 <code>http://localhost:5000/exercises/update/식별자 ID</code> 에 PUT 으로 요청을 해줍니다. 기존에 있던 Soccer 를 Tennis 로 바꿔 주고 duration 도 30, date 도 10일로 바꿔줍니다. updated! 문구를 확인 할 수 있습니다.
<img src="https://images.velog.io/images/run_dev_aiden/post/fa5bcd21-8338-46c7-ab89-472d2753ccec/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-10%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.39.25.png" alt=""></p>
<p><code>http://localhost:5000/exercises/</code> 에 GET으로 조회를 하여 변경 된 데이터를 확인 할 수 있습니다. 
<img src="https://images.velog.io/images/run_dev_aiden/post/aa251b6b-6dc5-41d7-9523-cac4badac71b/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-10%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%2010.40.00.png" alt=""></p>
<p>여기서 식별자를 사용 할 경우 PUT을 사용하고 아닐 경우 POST를 사용합니다.</p>
<p>데이터를 삭제 하기 위해서는 <code>http://localhost:5000/exercises/식별자 ID</code> 에 DELETE로 요청을 합니다.</p>
<p>여기까지 Node.js 서버에서 MongoDB의 <code>ODM(Object Document Mapping: DB에서 문서를 조회할 때 자바스크립트 객체로 바꿔주는 역할)</code> 중에 하나인 mongoose 를 사용해 데이터베이스에 연결과정을 알아보았습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[MongoDB 연결하기(1)]]></title>
            <link>https://velog.io/@run_dev_aiden/MongoDB-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@run_dev_aiden/MongoDB-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Wed, 09 Sep 2020 12:24:37 GMT</pubDate>
            <description><![CDATA[<h2 id="mongodb-연결하기">MongoDB 연결하기</h2>
<p>회원가입 로그인 부분은 생략 하였습니다.</p>
<h3 id="mongodb-설정하기">MongoDB 설정하기</h3>
<h4 id="1-로그인-후-cloud---atlas-경로에-들어와서-프로젝트를-생성해-줍니다">1. 로그인 후 Cloud - Atlas 경로에 들어와서 프로젝트를 생성해 줍니다.</h4>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/745b837b-b013-41e2-9839-3bcce7611df1/createProject.png" alt=""></p>
<h4 id="2-화면과-같이-build-a-cluster로-cluster를-생성합니다">2. 화면과 같이 build a Cluster로 Cluster를 생성합니다.</h4>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/8641194d-61d2-4d71-8f99-c9d936231f59/buildCluster.png" alt=""></p>
<h4 id="3-아래의-화면-처럼-클러스터를-생성하기-전에-설정-화면이-나옵니다-맨-하단에-free-라고-적혀있는-상태로-생성합니다">3. 아래의 화면 처럼 클러스터를 생성하기 전에 설정 화면이 나옵니다. 맨 하단에 Free 라고 적혀있는 상태로 생성합니다</h4>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/db9f6be2-8dac-405a-b11a-1cbb6bfe7adc/cluster.png" alt=""></p>
<h4 id="4-아래와-같은-화면이-나오고-생성하는데-1-3-분정도-소요됩니다">4. 아래와 같은 화면이 나오고 생성하는데 1-3 분정도 소요됩니다.</h4>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/84f79aea-fa73-4c21-8974-3e8630e20dc5/clusterbeingCreated.png" alt=""></p>
<h4 id="5-클러스터-생성-완료-화면입니다">5. 클러스터 생성 완료 화면입니다.</h4>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/60de30a2-3c79-40fa-9270-c64c98386319/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.31.43.png" alt=""></p>
<h4 id="6-이제-connect하기-위해-connect를-눌러-whitelist-ip-등록을-해줍니다">6. 이제 connect하기 위해 Connect를 눌러 whitelist IP 등록을 해줍니다</h4>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/cc81fe86-0ce4-408a-a301-00e4f93ac42b/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.32.17.png" alt=""></p>
<p><code>Whitelist IP</code> 란 승인 된 컴퓨터 IP주소를 나열하여 현재 사용하는 컴퓨터와 상호 작용 할 수 있도록 필터링 하는 IP 입니다.</p>
<h4 id="7-이제-데이터-베이스에-접근-할-수-있는-사용자를-등록합니다">7. 이제 데이터 베이스에 접근 할 수 있는 사용자를 등록합니다.</h4>
<p>Database Access 메뉴에 들어와 사용자를 생성을 해주면 됩니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/4ab3179e-4ddf-4b10-91ca-8a196d268a40/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.35.08.png" alt=""></p>
<h4 id="8-아래의-이미지는-사용자를-생성하는-등록-화면-입니다">8. 아래의 이미지는 사용자를 생성하는 등록 화면 입니다.</h4>
<p>저는 test 라고 하고 비밀번호를 설정하고 생성해 주었습니다. 
<img src="https://images.velog.io/images/run_dev_aiden/post/94372a15-a9e8-4c7a-a3e3-2f4d7eb7ca88/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%206.35.33.png" alt=""></p>
<h3 id="node-환경을-통해-연결">node 환경을 통해 연결</h3>
<p>Cluster 화면에서 Connect를 눌러 화면이 나오면 Connect your application 을 선택합니다.
<img src="https://images.velog.io/images/run_dev_aiden/post/43a56076-bda2-4b5a-b0f7-cf3dc2ebc7fe/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.32.08.png" alt=""></p>
<p>connection code를 copy 해줍니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/a5a57084-c340-4f76-8537-16bc73741783/%E1%84%89%E1%85%B3%E1%84%8F%E1%85%B3%E1%84%85%E1%85%B5%E1%86%AB%E1%84%89%E1%85%A3%E1%86%BA%202020-09-09%20%E1%84%8B%E1%85%A9%E1%84%92%E1%85%AE%209.32.15.png" alt=""></p>
<p><strong>Node.js server에서 mongoDB 설정을 합니다.</strong></p>
<pre><code class="language-javascript">const express = require(&quot;express&quot;); // express 미들웨어
const cors = require(&quot;cors&quot;); // cors 미들웨어
const mongoose = require(&quot;mongoose&quot;); // mongoose
require(&quot;dotenv&quot;).config(); // 환경변수를 위한 dotenv

const app = express();
const port = process.env.PORT || 5000;

app.use(cors());
app.use(express.json());

const uri = process.env.ATLAS_URI; // mongoDB Connect 정보
mongoose.connect(uri, {
  useNewUrlParser: true,
  useCreateIndex: true,
  useUnifiedTopology: true,
});
const connection = mongoose.connection;
connection.once(&quot;open&quot;, () =&gt; {
  console.log(&quot;MongoDB database connection succes&quot;);
});

app.listen(port, () =&gt; {
  console.log(`Server is running on port ${port}`);
});
</code></pre>
<p>mongoose 모듈을 불러오고 mongoose.connect를 사용해 연결해줍니다.
uri는 dotenv를 설정해 두었기 때문에 .env 파일 안에 MongoDB Connect 할 수 있는 사용자 정보와 URI가 있습니다. </p>
<pre><code class="language-jsx">// .env
ATLAS_URI=mongodb+srv://test:&lt;password&gt;@cluster0.bvh75.mongodb.net/&lt;dbname&gt;?retryWrites=true&amp;w=majority</code></pre>
<p>여기 까지 연결과정 이었습니다.</p>
<p>다음 글에서 Schema를 생성해 MongoDB 클라우드에 저장,삭제 등의 데이터베이스 흐름을 알아보도록 하겠습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[CORS( Cross-Origin Resource Sharing)]]></title>
            <link>https://velog.io/@run_dev_aiden/CORS-Cross-Origin-Resource-Sharing</link>
            <guid>https://velog.io/@run_dev_aiden/CORS-Cross-Origin-Resource-Sharing</guid>
            <pubDate>Tue, 08 Sep 2020 19:32:28 GMT</pubDate>
            <description><![CDATA[<h2 id="cors란">CORS란?</h2>
<p>CORS는 <code>Cross-orign Resource Sharing</code> 의 줄임말로, 한국어로 직역하면 교차 출처 리소스 공유라고 해석 할 수 있습니다.
한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근 할 수 있는 권한을 부여하도록 브라우져에게 알려주는 체제입니다.</p>
<p>웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다.</p>
<p>여기서 잠시 출처란 무엇인지 알아보겠습니다.</p>
<h3 id="출처">출처</h3>
<p>출처는 도메인, 프로토콜, 포트 나누어 집니다.</p>
<h4 id="도메인">도메인</h4>
<p>도메인은 식별하기 어려운 IP주소(192.x.x.x) 를 example.com 처럼 기억하기 쉽게 만들어주는 호스트 이름을 의미합니다.</p>
<pre><code class="language-javascript">IP는 인터넷에 연결되어 있는 장치들은 각각 장치를 식별 할 수 있는
192.168.0.1 등의 주소를 말합니다. (컴퓨터, 스마트폰, 타블릿, 서버 등등)</code></pre>
<h4 id="프로토콜">프로토콜</h4>
<p>프로토콜은 상호 간에 정의한 규칙을 의미하고 특정 기기 간에 데이터를 주고 받기 위해 정의 되었습니다.
브라우져와 서버 간에 데이터를 주고 받기 위한 방식으로 HTTP 프로토콜을 사용합니다.</p>
<h4 id="포트">포트</h4>
<p>포트는 네트워크 상에서 컴퓨터와 컴퓨터가 연결되는 통로라고 생각하시면 됩니다.</p>
<p>아래의 URL 을 보시면 http 는 프로토콜, <a href="http://www.example.com">www.example.com</a> 은 도메인 or 호스트 , :1234 는 port 입니다.</p>
<pre><code class="language-javascript">http://www.example.com:1234</code></pre>
<p>다시 <code>CORS</code> 에 대해 알아 보겠습니다.</p>
<p>한 출처에서 다른 출처로 자원을 요청할 때 cross-origin HTTP에 의해 요청이 되는데,
동일 출처 정책(Same-origin policy) 때문에 CORS 상황이 발생하면 외부서버에 요청한 데이터를 브라우저에서 보안목적으로 차단합니다. </p>
<p>즉 <code>localhost:3000</code> 에서 <code>localhost:8000</code> 자원 요청을 할 경우 출처가 다르기 때문에 동일 출처 정책 (Same-origin policy)에 의해 오류가 발생 하는 겁니다.</p>
<p>이를 해결하기 위한 방법은 응답을 주는 출처에서 Cross-origin HTTP 요청을 허가해 주면 됩니다.</p>
<p>허가 방법에는 
<code>Access-Control-Allow-Origin response</code> 헤더를 추가 해주면 해결 할수 있습니다.</p>
<p>예시로 Node.js를 통해 CORS 설정을 한다면 아래와 같습니다.</p>
<p><strong>방법1) 헤더 추가</strong></p>
<pre><code class="language-javascript">app.get(&#39;/&#39;, (req, res) =&gt;{
  res.header(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;);
});</code></pre>
<p><strong>방법2) CORS 미들웨어</strong></p>
<pre><code class="language-javascript">const express = require(&#39;express&#39;);
const cors = require(&#39;cors&#39;);
const app = express();

app.use(cors()); </code></pre>
<p>이처럼 모든 출처에 대해 허용을 할수 있습니다. 
하지만 보안적으로 취약 할수 있기 때문에 설정을 해줘야 합니다.</p>
<pre><code class="language-javascript">app.use(cors({origin: 허용 오리진 주소})) </code></pre>
<p>여기까지 CORS 에 대해 알아보았습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[web] Check Again]]></title>
            <link>https://velog.io/@run_dev_aiden/web-Check-Again</link>
            <guid>https://velog.io/@run_dev_aiden/web-Check-Again</guid>
            <pubDate>Fri, 04 Sep 2020 16:40:44 GMT</pubDate>
            <description><![CDATA[<h3 id="1-doctype-document-type-definition-dtd">1. DocType (Document Type Definition, DTD),</h3>
<p>DocType은 html문서에서 SGML이나 XML기반 문서 내에 그 문서가 특정 문서 형식 정의를 따름을 지정하는 것입니다.
HTML의 버전이 무엇인지 알려주는 역할이라고 생각 하면 됩니다.</p>
<p>HTML, XHTML, HTML5 유형 중에 정의를 해주어야 합니다.
문서형 정의를 생략하는 경우, 웹브라우져가 표준모드가 아닌 비표준 모드로 렌더링 되어 크로스 브라우징에 어려움을 겪을 수 있습니다. 정의는 HTML 문서의 최상위에 위치합니다.</p>
<h5 id="doctype-선언하기">DocType 선언하기</h5>
<pre><code class="language-javascript">&lt;!DOCTYPE html&gt;
//html 문서 최상위에 위치</code></pre>
<h4 id="이전-html문서">이전 HTML문서</h4>
<p>HTML4 or XHTML 에서는 선언이 DTD를 참조해야하므로 복잡할 수 있습니다.</p>
<p>HTML 4.01</p>
<pre><code class="language-javascript">&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01 Transitional//EN&quot; &quot;http://www.w3.org/TR/html4/loose.dtd&quot;&gt;</code></pre>
<p>XHTML 1.1</p>
<pre><code class="language-javascript">&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.1//EN&quot; &quot;http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd&quot;&gt;</code></pre>
<hr>
<h3 id="2-meta태그">2. meta태그</h3>
<p>메타태그는 웹서버와 웹 브라우져간에 상호교환이 되는 정보를 정의 하는데 사용합니다.
HTML 문서의 head 태그 사이에 입력하는 특수 태그이며 사이트 디자인에는 전혀 영향을 미치지 않습니다. 
페이지의 설명 요약, 핵심키워드, 제작자, 크롤링 정책 등 정보를 제공합니다.
(Description, Keywords, author, title)
이외에 반응형웹을 위한 viewport 설정과
호환성 보기를 위해 렌더링 모드를 X-UA-Compatible로 설정 할 수 있습니다. (IE=Edge 권장) </p>
<h5 id="http-equiv">http-equiv</h5>
<pre><code class="language-javascript">/*
 웹 브라우져가 서버에 명령을 내리는 속성으로 name 속성을 대신하여 사용될 수 있으며, HTML문서가 응답 헤더와 함께 웹 서버로부터 브라우져에 전송 되었을 때에만 의미를 갖습니다.
*/
&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot; /&gt;
</code></pre>
<pre><code class="language-javascript">// 검색 엔진에 의해 검색되는 단어 지정
&lt;meta name=&quot;keywords&quot; content=&quot;web, html, meta&quot; /&gt;
// 검색 결과에 표시되는 문자를 지정
&lt;meta name=&quot;Description&quot; content=&quot;web, html, meta&quot; /&gt;
// 검색 로봇 제어
&lt;meta name=&quot;Robots&quot; content=&quot;noindex, nofollow&quot; /&gt;
/*
All(기본값) : &#39;index, follow&#39; 를 지정한 것과 같습니다.
None : &#39;noindex, nofollow&#39; 를 지정한 것과 같습니다.
Index : 그 페이지를 수집 대상으로 합니다.
Follow : 그 페이지를 포함해 링크가 걸린 곳을 수집 대상으로 합니다.
Noindex : 그 페이지를 수집대상에서 제외합니다.
Nofollow : 그페이지를 포함해 링크가 걸린 곳을 수집 대상으로 하지 않습니다.
*/</code></pre>
<hr>
<h3 id="3-script-태그의-위치">3. script 태그의 위치</h3>
<p>Script 태그는 html에서 아무 위치에 있어도 됩니다.
하지만 Javascript 문에서 DOM이 다 렌더링 되지 않은 상태에서의 이벤트 실행 및 함수 호출로 에러가 날 수 있습니다. 그렇기 때문에 렌더링의 흐름을 파악하고 사용하길 권합니다.
보통 Document.onload 를 사용하여 DOM 렌더링이 완료 된 후 script문을 실행하여 해결합니다.</p>
<hr>
<h3 id="4-캡쳐링-버블링">4. 캡쳐링, 버블링</h3>
<p>캡쳐링과 버블링에 대해 이야기 하기 전에 알고 있어야 할 내용은 이벤트 등록입니다.
이벤트 등록은 사용자의 입력을 받기 위해 필요한 기능입니다. 
아래는 이벤트 등록 코드입니다.</p>
<pre><code class="language-jsx">&lt;button&gt;click button&lt;/button&gt;
let button = document.querySelector(&quot;button&quot;);
button.addEventListener(&quot;click&quot;, buttonClick);

function buttonClick(event){
 console.log(event); 
}</code></pre>
<p>버튼을 클릭 했을 때 buttonClick 함수를 실행시킵니다. 그리고 buttonClick 함수에 event인자가 넘어 옵니다. 콘솔에는 event 관련 정보가 출력됩니다.
이처럼 addEventListener() 웹 API는 웹개발자들이 화면에 동적인 기능을 추가하기 위해 자연스럽게 접하는 기능입니다. 이제 버블링과 캡쳐링을 알아보겠습니다.</p>
<h4 id="버블링">버블링</h4>
<p>버블링은 한 요소에 이벤트가 발생하면, 요소에 할당된 핸들러가 동작하고, 이어서 부모 요소의 핸들러가 동작합니다. 가장 최상위에 요소를 만날 때 까지 과정이 반복되고 요소 각각에 할당된 핸들러가 동작합니다.</p>
<pre><code class="language-html">&lt;form onClick=&quot;alert(&#39;form&#39;)&quot;&gt;Form
  &lt;div onClick=&quot;alert(&#39;div&#39;)&quot;&gt;Div
    &lt;p onClick=&quot;alert(&#39;p&#39;)&quot;&gt;P&lt;/p&gt;
  &lt;/div&gt;
&lt;/form&gt;</code></pre>
<p>안쪽에 P 태그를 클릭하면 P 요소에 클릭 핸들러가 동작합니다. 이어서 Div 핸들러가 동작하고 form 핸들러도 동작합니다. document 객체를 만날 때까지 각 요소에 할당 된 onClick 핸들러가 동작합니다
이러한 흐름을 버블링이라고 합니다. 이벤트가 제일 안쪽 부터 최상위 요소까지 거품처럼 퍼져 나가기 때문에 붙혀진 이름입니다.</p>
<h4 id="버블링-중단">버블링 중단</h4>
<p>버블링은 타깃 이벤트에서 시작해서 html 태그 요소를 거쳐 document 객체를 만날 때까지 각 노드에서 모두 발생 합니다. 하지만 상황에 따라 버블링을 중단해야 하는 경우가 있습니다. 버블링을 중단 하는 방법은 아래와 같습니다.</p>
<pre><code class="language-html">&lt;body onclick=&quot;alert(&#39;bubble&#39;)&quot;&gt;
  &lt;button onclick=&quot;event.stopPropagation()&quot;&gt;click&lt;/button&gt;
&lt;/body&gt;</code></pre>
<p>주의 할 점은 위쪽으로 일어나는 버블링은 막아주지만 다른 핸들러 동작은 막지 못합니다.
다른 핸들러의 동작도 막으려면 <code>event.stopImmediatePropagation()</code>을 사용 해야 합니다.</p>
<h4 id="캡쳐링">캡쳐링</h4>
<p>캡쳐링 단계를 이용해야 하는 경우는 흔치 않습니다.</p>
<pre><code class="language-html">&lt;table&gt;
  &lt;tr&gt;
    &lt;td onclick=&quot;alert(&#39;td&#39;)&quot;&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;</code></pre>
<p>td 태그를 클릭하면 이벤트가 최상위 요소에서 시작해 아래로 전파되고, 이벤트 타깃 요소에 도착해 실행 된 후 다시 위로 버블링 단계가 진행 됩니다. 
<code>on&lt;event&gt;</code> 프로퍼티나 html속성, addEventListener(event,handler) 를 이용한 핸들러는 캡쳐링에 대해 알수 없습니다. 이 핸들러는 두 번째 혹은 세 번째 단계의 이벤트 흐름(타깃,버블링 단계) 에서만 동작합니다.</p>
<p>캡쳐링 단계에서 이벤트를 잡아 내려면 addEventListener의 capture옵션을 true 로 설정해야 합니다.</p>
<pre><code class="language-javascript">elem.addEventListener(... {capture: true})
elem.addEventListener(..., true)</code></pre>
<h3 id="호이스팅">호이스팅</h3>
<p>호이스팅이란 코드에 선언 된 변수, 함수를 코드 상단으로 끌어 올리는 것을 말하며 이는 변수 범위가 전역범위인지 함수 범위인지에 따라 다르게 수행 될 수 있습니다.</p>
<pre><code class="language-javascript">if(true){
    var name = &#39;test&#39;
}
console.log(name);</code></pre>
<p>위 코드는 호이스팅에 의해서 아래와 같은 모양으로 바뀌게 됩니다.</p>
<pre><code class="language-javascript">var name; // 선언
if(true){
    name = &quot;test&quot;; // 할당
}
console.log(name);</code></pre>
<p>var name = &quot;test&quot; 라고 정의한 변수가 실제로는 선언과 할당이 분리되는 것입니다.</p>
<h4 id="var의-유효범위">var의 유효범위</h4>
<p>호이스팅시 선언문은 유효범위 최상단으로 올라갑니다.
함수내부에서 선언시 해당 함수에 유효범위(scope)안에서 동작하고, 전역범위 또한 하나의 함수 스코프처럼 동작합니다.</p>
<pre><code class="language-javascript">function test1(){
   if(true){
      var name = &#39;test&#39; 
   }
   console.log(name);
}
function test2(){
   for(var i=0; i&lt;5; i++){
        //..... 
   }
   console.log(i);
}
if(true){
  var num = 10; 
}
console.log(num);</code></pre>
<p>위 코드는 호이스팅에 의해 아래와 같은 모양으로 바뀌게 됩니다.</p>
<pre><code class="language-javascript">var num; //선언
function test1(){
     var name; //선언
      if(true){
         name = &#39;test&#39; //할당 
    }
      console.log(name);
}
function test2(){
     var i; // 선언
      for(i=0; i&lt;5; i++){//할당
      //...
    }
      console.log(i);
}
if(true){
     num = 10; // 할당 
}
console.log(num);</code></pre>
<h4 id="함수-호이스팅">함수 호이스팅</h4>
<p>함수 선언식 역시 호이스팅 대상입니다.
스코프 내에서 어떤 위치에서 함수 선언을 하든지 호출이 가능합니다.</p>
<pre><code class="language-javascript">function testFunc(){
     console.log(&#39;test&#39;); 
}</code></pre>
<p>위 코드는 아래와 같이 호이스팅 됩니다.</p>
<pre><code class="language-javascript">function testFunc(){
     console.log(&#39;test&#39;); 
}
testFunc();</code></pre>
<p>하지만 아래의 함수 표현식은 호이스팅의 영향을 받지 않습니다.</p>
<pre><code class="language-javascript">testFunc();
var testFunc = function(){
     console.log(&#39;test&#39;); 
}</code></pre>
<p>그 이유는 testFunc 는 변수이기 때문입니다.</p>
<pre><code class="language-javascript">var testFunc;

testFunc();

testFunc = function(){
     console.log(&#39;test&#39;); 
}</code></pre>
<h4 id="함수-변수-우선순위">함수, 변수 우선순위</h4>
<p>var 변수, 함수 선언식의 유효범위가 최상단으로 호이스팅 된다는 것을 알아봤습니다.
이제 호이스팅과 변수의 우선순위를 알아보겠습니다.</p>
<pre><code class="language-javascript">var testFunc = &#39;test&#39;;
funciton testFunc(){
     console.log(&#39;testFunc&#39;); 
}
function tester(){
     console.log(&#39;tester&#39;) 
}
var tester = &#39;hello&#39;;
console.log(typeof testFunc);
console.log(typeof tester);</code></pre>
<p> 위 코드는 아래와 같이 호이스팅 됩니다.</p>
<pre><code class="language-javascript">var testFunc;
var tester;
function testFunc(){
     console.log(&#39;testFunc&#39;); 
}
function tester(){
     console.log(&#39;tester&#39;); 
}
testFunc = &#39;test&#39;;
tester = &#39;hello&#39;;
console.log(typeof testFunc);
console.log(typeof tester);</code></pre>
<p>변수가 선언되고 함수가 할당 되어졌지만 다시 string으로 할당 값을 받아서
console에는 string 을 출력합니다.</p>
<h3 id="실행-컨텍스트">실행 컨텍스트</h3>
<p>ECMAScript 스펙에 따르면 실행 가능한 코드를 형상화하고 구분하는 추상적인 개념이라고 정의합니다.
자바스크립트 엔진에서 코드를 실행하기 위해서 실행에 필요한 정보를 알고 있어야 합니다.</p>
<pre><code>전역변수,지역변수, 매개변수, 객체의 프로퍼티
함수선언,
변수의 유효범위,
this</code></pre><p>실행 컨텍스트의 종류는 전역 컨텍스트, 함수 컨텍스트 두가지가 있습니다.
함수 내부에서 실행되는 코드를 제외하고는 모두 전역 컨텍스트로 볼수 있습니다.
함수 컨텍스트는 함수가 호출이 될 때 생성되고 동작이 완료되면 소멸됩니다.</p>
<h4 id="자바스크립트-동작-원리">자바스크립트 동작 원리</h4>
<p>자바스크립트의 특징 중 하나는 단일 스레드 언어라는 점입니다.
즉 동시에 하나의 작업만을 처리할 수 있다는 말입니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/50674687-bd19-4937-b374-1eced8a073f1/js%E1%84%8B%E1%85%AF%E1%86%AB%E1%84%85%E1%85%B5.png" alt=""></p>
<p>자바스크립트 엔진은 Memory Heap 과 Call Stack으로 구성되어 있습니다.
Memory Heap은 메모리 할당이 일어나는 곳입니다.
선언한 변수 함수 등이 담겨져 있습니다.
Call Stack은 함수 호출 시 쌓이는 곳입니다. 선입후출의 특징을 갖고 있습니다.</p>
<p>브라우져는 Web APIs, Event Table, Callback Queue, Event Loop등으로 구성되어 있습니다.
web APIs 는 DOM, AJAX, setTimeout 등 브라우져가 제공하는 API 입니다.
Web APIs 는 setTimeout이 Call Stack에 들어와 실행 되면 Browser API인 timer를 호출합니다.</p>
<pre><code class="language-javascript">setTimeout(function exec() {
  console.log(&#39;second&#39;);
}, 1000)</code></pre>
<p>Event Table 은 특정 이벤트(mouse move, click 등)가 발생 했을 때 어떤 Callback 함수가 호출 되야 하는지 알고 있는 자료구조 입니다. 위 코드에서 호출 된 timer가 종료 되면 이벤트가 발생 하는데 exec Callbacak 함수가 실행 되어야 한다는 것을 Event Table이 알고 있습니다.</p>
<p>Callback Queue는 이벤트 발생 시 실행해야 할 Callback 함수가 Callback Queue에 추가 됩니다.</p>
<p>Event Loop는 Call stack과 Callback Queue를 감시합니다.
Call stack이 비어있을 경우, Callback Queue에서 함수를 꺼내 Call stack에 추가합니다.</p>
<pre><code class="language-javascript">console.log(&#39;first&#39;);
setTimeout(function cb(){
  console.log(&#39;second&#39;);
}, 1000); // 0ms 뒤 실행
console.log(&#39;third&#39;);</code></pre>
<p>위 코드가 실행 될 때 각 구성요소들이 어떻게 동작하는지 알아보겠습니다.
<img src="https://images.velog.io/images/run_dev_aiden/post/82e93b00-99c3-45af-bfcc-92a1a95a45a8/js%E1%84%8B%E1%85%AF%E1%86%AB%E1%84%85%E1%85%B52.png" alt=""></p>
<ol>
<li>console.log(&#39;first&#39;)가 Call stack에 추가 됩니다.</li>
</ol>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/e002ecc2-b867-4870-ab8b-e584feb22cec/js%E1%84%8B%E1%85%AF%E1%86%AB%E1%84%85%E1%85%B53.png" alt="">
2. console.log(&#39;first&#39;)가 실행 되어 화면에 출력 한 뒤, Call Stack에서 제거 됩니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/5c9983af-320e-4f33-9982-be01b0051269/js4.png" alt="">
3. setTimeout 함수가 Call stack에 추가 됩니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/10fb4590-f972-4111-91dd-ef51e1e66196/js5.png" alt="">
4. setTimeout 함수가 실행 되면서 browser가 제공하는 timer WebAPI를 호출하고 CallStack에서 제거합니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/e87a6f5c-7d80-4401-816d-3ab8c1493e38/js6.png" alt="">
5. console.log(&#39;third&#39;) 가 Call stack에 추가됩니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/c93a843e-117b-40e5-9f44-2229cdff15b3/js7.png" alt="">
6. console.log(&#39;third&#39;) 가 실행되어 화면에 출력 되고 Call stack에서 제거 됩니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/fcaca0c3-010b-47af-a524-78ca6697cf42/js8.png" alt="">
7. setTimeout 함수에 전달한 0ms 시간이 지난뒤 Callback으로 전달한 cb함수가 Callback Queue에 추가됩니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/2b55e6b2-43ad-4658-a818-b5e4d64e1832/js9.png" alt="">
8. Event Loop는 Call Stack이 비어있는것을 확인 하고 Callback Queue를 살펴봅니다.
cb함수를 발견한 Event Loop는 CallStack에 cb를 추가합니다.
Event Loop는 Call stack이 비어 있을 경우에 Callback Queue에서 대기중이던 함수를 Call Stack에 추가합니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/dd9bfd30-ff6b-442b-898a-1b274d2be2bb/js10.png" alt="">
9. cb함수가 실행 되고 내부의 console.log(&#39;second&#39;) 가 call stack에 추가 됩니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/0257dc7c-682c-438e-b672-37b8f453653a/js11.png" alt="">
10. console.log(&#39;second&#39;) 가 화면에 출력되고 Call stack에서 제거됩니다.</p>
<p><img src="https://images.velog.io/images/run_dev_aiden/post/328beddd-4ff8-4ffa-b344-13cda09f648c/js12.png" alt="">
11. cb함수가 Call stack에서 제거됩니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[RESTful API]]></title>
            <link>https://velog.io/@run_dev_aiden/RESTful-API</link>
            <guid>https://velog.io/@run_dev_aiden/RESTful-API</guid>
            <pubDate>Tue, 01 Sep 2020 08:52:49 GMT</pubDate>
            <description><![CDATA[<p><img src="https://images.velog.io/images/run_dev_aiden/post/5c70e369-df3c-492a-b175-1786378d7e4d/RESTful.jpg" alt=""></p>
<h2 id="restful-api란">RESTful API란?</h2>
<p>&#39;스타일&#39; 또는 &#39;패턴&#39;이라고도 하며 방법론이라고 생각하면 쉽다.</p>
<h4 id="rest한-방식의-api">REST한 방식의 API</h4>
<pre><code class="language-javascript">1. HTTP Protocol 기반이다.
2. 리소스는 URI로 표현하고 고유해야 한다.
3. URI는 단순하고 직관적인 구조여야 한다.
4. 리소스 상태는 HTTP Methods를 활용해서 구분한다.
5. xml/json을 활용해서 데이터를 전송한다.</code></pre>
<h4 id="http-methods">HTTP Methods</h4>
<pre><code class="language-javascript">POST   (create)
GET    (Retrieve)
PUT    (Update)
DELETE (Delete)</code></pre>
<h4 id="api-design">API Design</h4>
<pre><code class="language-javascript">복수명사를 사용한다 (/datas)
필요하면 URL에 하위 자원을 표현한다. (/datas/12)
필터조건을 허용할 수 있다. (/datas?state=active)</code></pre>
<h4 id="example">Example</h4>
<table>
<thead>
<tr>
<th>URL</th>
<th>Methods</th>
<th>Description</th>
</tr>
</thead>
<tbody><tr>
<td>/datas/</td>
<td>GET</td>
<td>모든 데이타리스트 가져오기</td>
</tr>
<tr>
<td>/datas/</td>
<td>POST</td>
<td>데이타 추가</td>
</tr>
<tr>
<td>/datas/:title</td>
<td>GET</td>
<td>title 해당 데이타 가져오기</td>
</tr>
<tr>
<td>/datas/:title</td>
<td>DELETE</td>
<td>title 해당 데이타 삭제</td>
</tr>
<tr>
<td>/datas/:title</td>
<td>PUT</td>
<td>title 해당 데이타 업데이트</td>
</tr>
<tr>
<td>/datas?min=9</td>
<td>GET</td>
<td>데이타 리스트/필터조건 최소 9</td>
</tr>
</tbody></table>
]]></description>
        </item>
    </channel>
</rss>