From f902cd2165fa67725f39e991e3d0fc0deab95e4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=EC=9E=84=EA=B8=B0=EC=9B=90=20=28Giwon=20Lim=29?= Date: Wed, 8 Dec 2021 23:00:24 +0900 Subject: [PATCH] Delete devnote directory --- ...0 \354\227\220\353\237\254\353\223\244.md" | 16 -- devnote/README.md | 3 - ...0\353\212\245 \354\266\224\352\260\200.md" | 165 ------------------ ...0 \355\225\264\352\262\260\353\262\225.md" | 58 ------ ...0\353\212\245 \352\265\254\355\230\204.md" | 161 ----------------- 5 files changed, 403 deletions(-) delete mode 100644 "devnote/Docker/\352\270\260\354\264\210\354\240\201\354\235\270 \354\227\220\353\237\254\353\223\244.md" delete mode 100644 devnote/README.md delete mode 100644 "devnote/React/iamport API \352\262\260\354\240\234 \352\270\260\353\212\245 \354\266\224\352\260\200.md" delete mode 100644 "devnote/Spring/\355\206\265\354\213\240\355\225\240 \353\225\214 CORS \354\235\264\354\212\210 \355\225\264\352\262\260\353\262\225.md" delete mode 100644 "devnote/vuepress/vuepress utterances \353\214\223\352\270\200 \352\270\260\353\212\245 \352\265\254\355\230\204.md" diff --git "a/devnote/Docker/\352\270\260\354\264\210\354\240\201\354\235\270 \354\227\220\353\237\254\353\223\244.md" "b/devnote/Docker/\352\270\260\354\264\210\354\240\201\354\235\270 \354\227\220\353\237\254\353\223\244.md" deleted file mode 100644 index 88519d982..000000000 --- "a/devnote/Docker/\352\270\260\354\264\210\354\240\201\354\235\270 \354\227\220\353\237\254\353\223\244.md" +++ /dev/null @@ -1,16 +0,0 @@ -# 기초적인 에러들 - -### container "containerID" is using its referenced image "imageID" - -`docker rmi '이미지'`를 입력했을 때 이미지가 삭제가 되지 않는 에러가 났다. - -해당 이미지로 만들어진 컨테이너가 실행중이기 때문에 에러가 났었다. - -```shell -Error response from daemon: conflict: unable to remove repository reference "httpd" (must force) - container a0435577ff74 is using its referenced image ad17c88403e2 -``` - -해석하자면, id가 `a0435577ff74`인 컨테이너가 `ad17c88403e2`라는 이미지를 참조중이라고 한다. -(컨테이너의 실행 유무는 상관없다.) - -해결방법은 간단하다. 참조되는 이미지를 다 삭제해주면 된다. diff --git a/devnote/README.md b/devnote/README.md deleted file mode 100644 index 8f639701a..000000000 --- a/devnote/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# 개발노트 ~~(강아지발 아님)~~ - -### 개발하면서 겪었던 경험이나 에러해결에 관해 적습니다. diff --git "a/devnote/React/iamport API \352\262\260\354\240\234 \352\270\260\353\212\245 \354\266\224\352\260\200.md" "b/devnote/React/iamport API \352\262\260\354\240\234 \352\270\260\353\212\245 \354\266\224\352\260\200.md" deleted file mode 100644 index f06c9ab82..000000000 --- "a/devnote/React/iamport API \352\262\260\354\240\234 \352\270\260\353\212\245 \354\266\224\352\260\200.md" +++ /dev/null @@ -1,165 +0,0 @@ -# 아임포트(iamport) API 결제 기능 추가 - -이 글은 리액트에서 아임포트 API를 다루는 방법을 설명합니다. - -## 1. 세팅하기 - 라이브러리 호출 - -React와 useEffect를 import 해준다. - -useEffect를 사용하는 이유는 브라우저가 이 파일을 처음 호출했을 때 - -useEffect의 내부코드가 변하는 것이 없다면 컴포넌트가 호출되는 첫 시점에 한번만 호출된다. - -그리고 컴포넌트가 소멸하기 직전에 useEffect의 리턴을 호출한다. - -react에서 아래와 같이 jquery와 iamport 를 호출할 수 있다. - -```jsx -import React, { useEffect } from 'react'; - -const Payment = (effect, deps) => { - useEffect(() => { - const jquery = document.createElement("script"); - jquery.src = "https://code.jquery.com/jquery-1.12.4.min.js"; - const iamport = document.createElement("script"); - iamport.src = "https://cdn.iamport.kr/js/iamport.payment-1.1.7.js"; - document.head.appendChild(jquery); - document.head.appendChild(iamport); - return () => { - document.head.removeChild(jquery); - document.head.removeChild(iamport); - } - }, []); - - - return (); -} -``` - -
- -## 2. 가맹점 식별하기 - -pg 는 어느 플랫폼을 이용하여 결제할지 물어보는거고, - -pay_method는 결제수단을 말하는것이다. card로 설정하면 카드결제밖에 되지않는다. - -이니시스에서 카카오페이를 사용하더라도 결제가 실패한다. 이건 좀 더 알아볼 예정이다. - -그리고 코드 아랫쪽에 IMP.request_pay(data, callback)에 들어가는 callback을 구현해야한다. - -```jsx{7} -const onClickPayment = () => { -const { IMP } = window; -IMP.init('imp77220765'); // 가맹점 식별코드 - - // 결제 데이터 정의 - const data = { - pg: 'html5_inicis', // PG사 (필수항목) - pay_method: 'card', // 결제수단 (필수항목) - merchant_uid: `mid_${new Date().getTime()}`, // 결제금액 (필수항목) - name: '결제 테스트', // 주문명 (필수항목) - amount: '1000', // 금액 (필수항목) - custom_data: { - name: '부가정보', - desc: '세부 부가정보' - }, - buyer_name: '임기원', // 구매자 이름 - buyer_tel: '01099558701', // 구매자 전화번호 (필수항목) - buyer_email: 'l4279625@gmail.com', // 구매자 이메일 - buyer_addr: '주소', - buyer_postalcode: '우편번호' - // .... - }; - - IMP.request_pay(data, callback); - } -``` - -참고 : [https://docs.iamport.kr/implementation/payment](https://docs.iamport.kr/implementation/payment) - -
- -## 3. 콜백 구현 - -```jsx -const callback = (response) => { - const { success, error_msg, imp_uid, merchant_uid, pay_method, paid_amount, status } = response; - - if (success) { - alert('결제 성공'); - } else { - alert(`결제 실패 : ${error_msg}`); - } -}; -``` - -
- -## 3. 전체 코드 - -```jsx -import React, { useEffect } from 'react'; - -const Payment = (effect, deps) => { - useEffect(() => { - const jquery = document.createElement('script'); - jquery.src = 'https://code.jquery.com/jquery-1.12.4.min.js'; - const iamport = document.createElement('script'); - iamport.src = 'https://cdn.iamport.kr/js/iamport.payment-1.1.7.js'; - document.head.appendChild(jquery); - document.head.appendChild(iamport); - return () => { - document.head.removeChild(jquery); - document.head.removeChild(iamport); - }; - }, []); - - const onClickPayment = () => { - const { IMP } = window; - IMP.init('imp77220765'); // 가맹점 식별코드 - - // 결제 데이터 정의 - const data = { - pg: 'html5_inicis', // PG사 (필수항목) - pay_method: 'card', // 결제수단 (필수항목) - merchant_uid: `mid_${new Date().getTime()}`, // 결제금액 (필수항목) - name: '결제 테스트', // 주문명 (필수항목) - amount: '1000', // 금액 (필수항목) - custom_data: { - name: '부가정보', - desc: '세부 부가정보', - }, - buyer_name: '임기원', // 구매자 이름 - buyer_tel: '01099558701', // 구매자 전화번호 (필수항목) - buyer_email: 'l4279625@gmail.com', // 구매자 이메일 - buyer_addr: '구천면로 365-13', - buyer_postalcode: '05258', - }; - - IMP.request_pay(data, callback); - }; - - const callback = (response) => { - const { success, error_msg, imp_uid, merchant_uid, pay_method, paid_amount, status } = response; - - if (success) { - alert('결제 성공'); - } else { - alert(`결제 실패 : ${error_msg}`); - } - }; - - return ( - <> - - - ); -}; - -export default Payment; -``` - -
- -여기까지 하면 결제기능이 담긴 Component 하나 완성이다. diff --git "a/devnote/Spring/\355\206\265\354\213\240\355\225\240 \353\225\214 CORS \354\235\264\354\212\210 \355\225\264\352\262\260\353\262\225.md" "b/devnote/Spring/\355\206\265\354\213\240\355\225\240 \353\225\214 CORS \354\235\264\354\212\210 \355\225\264\352\262\260\353\262\225.md" deleted file mode 100644 index 9a48e5f89..000000000 --- "a/devnote/Spring/\355\206\265\354\213\240\355\225\240 \353\225\214 CORS \354\235\264\354\212\210 \355\225\264\352\262\260\353\262\225.md" +++ /dev/null @@ -1,58 +0,0 @@ -# 통신 시에 CORS 이슈 해결법 - -보통 백단과 프론트단 분리하여 실행시키면 CORS 이슈를 많이 보게 된다. - -CORS(크로스 도메인 이슈)를 해결하는 방법은 몇 가지가 있다. - -CORS 이슈는 보통 서버측에서 해결하는 것이 보편적인 방법이다. - -## @CrossOrigin(origins = "\*") - -:::tip 작성방법 -@CrossOrigin(origins = "**허용주소:포트**") -::: - -해당 어노테이션을 통신하는 컨트롤러에 붙여주면 간단히 해결된다. - -별표 대신 주소를 넣어도 된다. - -
- -## resp.setHeader() - -:::tip 작성방법 -resp.setHeader("Access-Control-Allow-Origin", req.getHeader("**허용주소:포트**")); -::: - -요청이 들어오면 response로 헤더를 직접 허용해준다. -요청 방식(GET, POST)에 따라서 허용해줄 수도 있고, 그 외에 옵션도 다양하다. - -```java{15} -public class LogFilter implements Filter { - - // ... - - @Override - public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) - throws IOException, ServletException { - // ... - - HttpServletResponse resp = (HttpServletResponse) response; - // req.getHeader("Origin") -> http://localhost:3000 - - // Origin 대신 "주소:포트번호" 형식으로 넣어도 된다. - // 이전 방법인 어노테이션과 똑같이 동작한다. - resp.setHeader("Access-Control-Allow-Origin", req.getHeader("Origin")); - resp.setHeader("Access-Control-Allow-Credentials", "true"); - resp.setHeader("Access-Control-Allow-Methods", "GET, POST"); - resp.setHeader("Access-Control-Max-Age", "10"); - resp.setHeader("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With, remember-me"); - - // ... - - } - - // ... - -} -``` diff --git "a/devnote/vuepress/vuepress utterances \353\214\223\352\270\200 \352\270\260\353\212\245 \352\265\254\355\230\204.md" "b/devnote/vuepress/vuepress utterances \353\214\223\352\270\200 \352\270\260\353\212\245 \352\265\254\355\230\204.md" deleted file mode 100644 index 18538997b..000000000 --- "a/devnote/vuepress/vuepress utterances \353\214\223\352\270\200 \352\270\260\353\212\245 \352\265\254\355\230\204.md" +++ /dev/null @@ -1,161 +0,0 @@ -# vuepress utterances 댓글 기능 구현 - -> vuepress 기본 테마를 기준으로 설명합니다. - -utterances는 본인의 깃허브 레포지토리를 이용하여 댓글을 관리할 수 있다. - -레포지토리의 issue 기능을 통해 댓글을 구현한 것으로 보인다. - -글을 따로 작성하는 이유는 다른 분들도 댓글 기능 추가에 대해 작성해주셨지만 - -시간이 지나서 방법이 바뀐건지 적용이 제대로 되질 않았었다. - -삽질 한 경험을 토대로 어떤 방법으로 성공했는지 작성하고자 한다. - -## github 설정 - -첫 번째로 해야 할 일은 댓글을 받아줄 레포지토리를 만드는 것이다. - -혹은 기존의 레포지토리를 사용해도 좋다. - -[https://github.com/apps/utterances](https://github.com/apps/utterances) - -위의 링크를 통해 댓글을 관리해줄 레포지토리를 지정해준다. - -이제 vuepress의 설정만 남았다. - -
- -## vuepress 설정 - -vuepress를 사용하는 이상 utterances를 컴포넌트화 시켜야한다. - -vuepress는 components라는 폴더 내에 vue파일을 만들어 놓으면 언제든지 끌어와서 사용할 수 있다. - -만약 본인이 마크다운을 작성하다가 특정 위치에 컴포넌트를 사용하고 싶으면 그냥 사용하면 된다. - -일단 Comment 라는 이름으로 utterances 컴포넌트를 만들어보자. - -```js -// .vuepress/components/Comment.vue - - -``` - -Comment.vue 파일을 만들었으면 사실상 90%는 한 것이다. - -만약 마크다운을 작성하다가 댓글 기능을 달고 싶다면 바로 사용하면 된다. - -```md -# 안녕? - -## 하이? - - -``` - -이렇게 하면 html로 변환되면서 우리가 만들어놓은 Comment.vue가 저 태그에 들어간다. - -하지만 이렇게 하는것 보다 다들 자동화를 하고 싶어할거라는걸 다 안다. - -일괄적으로 모든 페이지에 댓글 기능을 넣어보자. - -
- -## 모든 페이지에 댓글 기능 추가하기 - -처음에 말했듯이 기본 테마를 사용한다는 가정하에 설명을 진행한다. - -### 1. theme/index.js 추가 - -.vuepress에 theme 폴더를 생성하고 index.js를 만들어준다. - -기본 테마를 확장하기 위해서는 theme-default 라는 기능이 있어야한다. - -```shell -npm i -D @vuepress/theme-default -``` - -해당 기능을 인스톨 해줬으면 extend해주자. - -```js -// .vuepress/theme/index.js -module.exports = { - extend: '@vuepress/theme-default', -}; -``` - -### 2. theme/Layout.vue 추가 - -theme 폴더에 Layout.vue를 추가해주자. - -그리고 아래와 같이 작성해주자. - -```js - - - - -``` - -가장 중요한건 저 slot속성은 꼭 작성해주어야 한다. - -[네임드 슬롯 관련 예제](https://github.com/vuejs/vuepress/blob/master/packages/%40vuepress/theme-vue/layouts/Layout.vue#L3) - -위의 공식 예제를 보면 sidebar-top과 page-bottom이라는 네임드 슬롯을 사용하는 것으로 보인다. - -나는 page-bottom을 이용하였다. - -```js -// .vuepress/theme/Layout.vue - - - -``` - -### Reference - -[Vuepress + Utterances](https://junilhwang.github.io/TIL/Vuepress/Utterances/) -[vuepress + utterances (블로그에 github 댓글 추가하기)](https://kyounghwan01.github.io/blog/Vue/vuepress/vuepress-github-comment/) -[뷰프레스 Disqus 댓글 기능 구현하기 + layout 확장하기](https://limdongjin.github.io/vuejs/vuepress/layout-extend.html#disqus-%E1%84%83%E1%85%A2%E1%86%BA%E1%84%80%E1%85%B3%E1%86%AF-%E1%84%80%E1%85%B5%E1%84%82%E1%85%B3%E1%86%BC%E1%84%8B%E1%85%B3%E1%86%AF-component%E1%84%85%E1%85%A9-%E1%84%80%E1%85%AE%E1%84%92%E1%85%A7%E1%86%AB%E1%84%92%E1%85%A2%E1%84%87%E1%85%A9%E1%84%8C%E1%85%A1)