Geolocation API로 실시간 위치 정보 가져오기

2024. 9. 8. 18:58· JavaScript

https://developer.mozilla.org/en-US/docs/Web/API/Geolocation_API

 

Geolocation API - Web APIs | MDN

The Geolocation API allows the user to provide their location to web applications if they so desire. For privacy reasons, the user is asked for permission to report location information.

developer.mozilla.org

1. Geolocation API란?

Geolocation API는 웹사이트가 사용자의 기기에서 위치 정보를 요청할 수 있도록 해주는 기능입니다.

위치 정보는 사용자의 허락을 받아야만 가져올 수 있습니다.

2. 위치 정보 가져오기: getCurrentPosition()

위치 정보를 한 번만 가져오려면 getCurrentPosition() 메서드를 사용합니다.

이 메서드는 성공 시 실행될 함수(필수), 실패 시 실행될 함수(필수), 그리고 추가 설정 옵션(선택)을 인수로 받습니다.

JAVASCRIPT

 

navigator.geolocation.getCurrentPosition(
    (position) => {
        console.log("위도: " + position.coords.latitude);
        console.log("경도: " + position.coords.longitude);
    },
    (error) => {
        console.error("오류 발생: ", error);
    }
);

3. 위치 정보 객체 (position) 자세히 알아보기

성공적으로 위치 정보를 가져오면 position 객체가 반환됩니다.

이 객체에는 사용자 기기의 여러 위치 정보가 들어 있습니다.

  • coords.latitude: 위도 (ex: 37.5172)
  • coords.longitude: 경도 (ex: 127.0473)
  • coords.altitude: 고도, 미터 단위 (사용할 수 없으면 null).
  • coords.accuracy: 위치의 정확도, 미터 단위.
  • coords.altitudeAccuracy: 고도의 정확도 (사용할 수 없으면 null).
  • coords.heading: 기기가 가리키고 있는 방향 (정지 상태일 경우 null).
  • coords.speed: 기기의 이동 속도, m/s 단위 (정지 상태일 경우 null)
JAVASCRIPT

 

navigator.geolocation.getCurrentPosition(
    (position) => {
        const { latitude, longitude, accuracy, altitude, heading, speed } = position.coords;
        console.log(`위도: ${latitude}, 경도: ${longitude}`);
        console.log(`정확도: ${accuracy}m`);
        console.log(`고도: ${altitude !== null ? altitude + "m" : "정보 없음"}`);
        console.log(`방향: ${heading !== null ? heading + "°" : "정지 상태"}`);
        console.log(`속도: ${speed !== null ? speed + "m/s" : "정지 상태"}`);
    }
);

4. 오류 처리

위치 정보를 가져오는 중 발생하는 오류는 크게 세 가지로 나눌 수 있습니다.

  • PERMISSION_DENIED: 사용자가 위치 정보 접근을 거부한 경우.
  • POSITION_UNAVAILABLE: 기기의 위치 정보를 사용할 수 없는 경우.
  • TIMEOUT: 위치 정보를 가져오는 시간이 초과된 경우.
JAVASCRIPT

 

navigator.geolocation.getCurrentPosition(
    (position) => {
        // 위치 정보를 성공적으로 가져옴
    },
    (error) => {
        switch (error.code) {
            case error.PERMISSION_DENIED:
                alert("위치 정보 접근이 거부되었습니다.");
                break;
            case error.POSITION_UNAVAILABLE:
                alert("위치 정보를 사용할 수 없습니다.");
                break;
            case error.TIMEOUT:
                alert("위치 정보를 가져오는 데 시간이 너무 오래 걸렸습니다.");
                break;
            default:
                alert("알 수 없는 오류가 발생했습니다.");
        }
    }
);

5. 위치 요청 시 옵션 설정하기

getCurrentPosition() 메서드는 추가적인 옵션을 설정할 수 있습니다.

  • enableHighAccuracy: 위치 정보의 정확도를 높일지 여부(기본값 false)
    true로 설정하면 더 정확한 위치 정보를 제공하지만, 배터리 소모량이 증가할 수 있습니다.
  • timeout: 위치 정보를 가져오는 데 걸리는 최대 시간 (밀리초 단위).
  • maximumAge: 이전 위치 정보를 얼마 동안 캐시할지 (밀리초 단위). 0으로 설정 시 항상 최신 정보를 요청합니다.
JAVASCRIPT

 

navigator.geolocation.getCurrentPosition(
    (position) => {
        console.log(`위도: ${position.coords.latitude}, 경도: ${position.coords.longitude}`);
    },
    (error) => {
        console.error("위치 정보를 가져오는 중 오류 발생: ", error);
    },
    {
        enableHighAccuracy: true,  // 고정밀도 위치 요청
        timeout: 5000,             // 5초 이내에 위치 정보를 가져오지 않으면 오류 처리
        maximumAge: 0              // 캐시된 위치 정보 사용 안 함
    }
);

 

https://hy-un.tistory.com/entry/Geolocation-API%EB%A1%9C-%EC%8B%A4%EC%8B%9C%EA%B0%84-%EC%9C%84%EC%B9%98-%EC%A0%95%EB%B3%B4-%EA%B0%80%EC%A0%B8%EC%98%A4%EA%B8%B0

Geolocation API 사용하기

보안 컨텍스트: 이 기능은 일부 또는 모든 지원 브라우저 보안 컨텍스트 (HTTPS)에서만 사용할 수 있습니다.

Geolocation API는 사용자의 현재 위치를 가져오는 API로, 지도에 사용자 위치를 표시하는 등 다양한 용도로 사용할 수 있습니다. 이 글에서는 Geolocation API의 기초 사용법을 설명합니다.

geolocation 객체

Geolocation API navigator.geolocation 객체를 통해 사용할 수 있습니다.

geolocation 객체가 존재하는 경우 위치 정보 서비스를 지원하는 것입니다. 객체의 존재 여부는 다음과 같이 알아낼 수 있습니다.

jsCopy to Clipboard
if ("geolocation" in navigator) {
  /* 위치정보 사용 가능 */
} else {
  /* 위치정보 사용 불가능 */
}

현재 위치 가져오기

사용자의 현재 위치는 getCurrentPosition() 메서드를 호출해서 가져올 수 있습니다. 이 메서드는 사용자의 위치를 탐지하는 비동기 요청을 시작하고, 위치 관련 하드웨어에 최신 정보를 요청하며, 위치를 알아낸 후 주어진 콜백 함수를 호출합니다. 선택적으로, 오류가 발생하면 호출할 콜백을 두 번째 매개변수로 지정할 수 있습니다. 또 다른 선택 사항인 세 번째 매개변수는 위치 정보의 최대 수명, 요청의 최대 대기시간, 고정밀 위치정보 여부 등의 옵션을 담은 객체입니다.

참고: getCurrentPosition()의 기본 설정에서는 정밀도가 낮더라도 최대한 빠르게 응답을 반환하므로, 정확도보다 속도가 중요한 상황에서 유용합니다. 예를 들어, GPS 기능을 가진 장비는 보정 과정에 수 분이 걸릴 수도 있으므로 그동안 IP 위치와 Wi-Fi 등 정확하지 않은 출처에 기반한 위치 정보를 반환할 수 있습니다.

jsCopy to Clipboard
navigator.geolocation.getCurrentPosition((position) => {
  doSomething(position.coords.latitude, position.coords.longitude);
});

위의 예제는 사용자 위치가 확인되면 doSomething() 함수를 실행합니다.

현재 위치 추적하기

장치의 이동이나 위치 정밀도 향상으로 인해 위치 정보가 바뀔 때 호출할 콜백 함수를 watchPosition() 메서드로 설정할 수 있습니다. 이 메서드의 매개변수는 getCurrentPosition()과 같습니다. 이 콜백은 여러 번 호출될 수 있으므로 브라우저가 사용자의 움직임에 따라 위치를 업데이트하거나, 고정밀 위치 기술을 적용해 보다 정밀한 위치를 표시할 수 있습니다. getCurrentPosition()과 마찬가지로 선택 사항인 오류 콜백 역시 여러 번 호출될 수 있습니다.

참고: getCurrentPosition()을 먼저 호출하지 않아도 watchPosition()을 사용할 수 있습니다.

jsCopy to Clipboard
const watchID = navigator.geolocation.watchPosition((position) => {
  doSomething(position.coords.latitude, position.coords.longitude);
});

watchPosition() 메서드는 위치 추적 요청을 식별할 수 있는 고유 숫자를 반환합니다. 이 숫자를 clearWatch() 메서드에 전달하면 해당 위치 추적을 종료할 수 있습니다.

jsCopy to Clipboard
navigator.geolocation.clearWatch(watchID);

응답 미세 조정

getCurrentPosition() watchPosition() 둘 다 성공 콜백, 실패 콜백, 그리고 옵션 객체를 받을 수 있습니다.

이 옵션 객체로는 고정밀도 활성화 여부, 위치 정보의 최대 수명(수명이 끝나기 전에는 이전에 반환했던 위치 정보를 저장했다가, 같은 요청을 또 받으면 그대로 반환합니다), 그리고 위치 정보 요청의 응답을 기다릴 최대 대기시간을 지정할 수 있습니다.

옵션 객체를 사용한 watchPosition의 호출 예시는 다음과 같습니다.

jsCopy to Clipboard
function success(position) {
  doSomething(position.coords.latitude, position.coords.longitude);
}

function error() {
  alert("죄송합니다. 위치 정보를 사용할 수 없습니다.");
}

const options = {
  enableHighAccuracy: true,
  maximumAge: 30000,
  timeout: 27000,
};

const watchID = navigator.geolocation.watchPosition(success, error, options);

위치 표현

사용자의 위치는 GeolocationPosition 객체 인스턴스와, 그 안의 GeolocationCoordinates 객체 인스턴스로 표현됩니다.

GeolocationPosition은 오직 두 가지, GeolocationCoordinates 인스턴스를 가진 coords 속성과, 위치 정보의 기록 시점을 타임스탬프(Unix 시간, 밀리초)로 나타내는 timestamp 속성만 갖습니다.

GeolocationCoordinates 인스턴스는 여러 속성을 갖지만, 그중 가장 많이 쓰게 될 두 가지는 지도 위에 위치를 표시할 때 필요한 latitude와 longitude입니다. 따라서 대부분의 Geolocation 성공 콜백은 아래와 같이 꽤 간단한 형태입니다.

jsCopy to Clipboard
function success(position) {
  const latitude = position.coords.latitude;
  const longitude = position.coords.longitude;

  // 위도와 경도를 사용해 작업 수행
}

그러나 GeolocationCoordinates 객체에서 고도, 속도, 장치의 방향, 위경도와 고도의 오차범위 등 다른 다양한 정보도 가져올 수 있습니다.

오류 처리

getCurrentPosition() 또는 watchPosition()에 오류 콜백을 제공한 경우, 콜백은 첫 번째 매개변수로 GeolocationPositionError 객체를 받습니다. 해당 객체는 오류의 유형을 나타내는 code 속성과, 사람이 읽을 수 있는 형태로 오류 코드의 뜻을 설명한 message 속성을 갖습니다.

다음 형태로 사용할 수 있습니다.

jsCopy to Clipboard
function errorCallback(error) {
  alert(`ERROR(${error.code}): ${error.message}`);
}

예제

다음 예제는 Geolocation API를 사용해 사용자의 위경도를 가져오는 데 성공하면, 사용자의 위치로 향하는 openstreetmap.org 링크를 생성하고 하이퍼링크에 지정합니다.

HTML

htmlCopy to Clipboardplay
<button id="find-me">내 위치 보기</button><br />
<p id="status"></p>
<a id="map-link" target="_blank"></a>

JavaScript

jsCopy to Clipboardplay
function geoFindMe() {
  const status = document.querySelector("#status");
  const mapLink = document.querySelector("#map-link");

  mapLink.href = "";
  mapLink.textContent = "";

  function success(position) {
    const latitude = position.coords.latitude;
    const longitude = position.coords.longitude;

    status.textContent = "";
    mapLink.href = `https://www.openstreetmap.org/#map=18/${latitude}/${longitude}`;
    mapLink.textContent = `위도: ${latitude} °, 경도: ${longitude} °`;
  }

  function error() {
    status.textContent = "현재 위치를 가져올 수 없음";
  }

  if (!navigator.geolocation) {
    status.textContent = "브라우저가 위치 정보를 지원하지 않음";
  } else {
    status.textContent = "위치 파악 중…";
    navigator.geolocation.getCurrentPosition(success, error);
  }
}

document.querySelector("#find-me").addEventListener("click", geoFindMe);



문제점

Bitbucket과는 달리 Github에는 기본적으로 100MB 이상의 파일을 올릴 수 없다.

Conditions for large files — User Documentation
https://help.github.com/articles/conditions-for-large-files/

그래서 100MB보다 큰 크기의 파일을 올리려고 시도하면 다음과 같은 경고 메시지를 보게 된다.

$ git push
Counting objects: 3086, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (2980/2980), done.
Writing objects: 100% (3086/3086), 363.25 MiB | 935.00 KiB/s, done.
Total 3086 (delta 1236), reused 111 (delta 57)
remote: error: GH001: Large files detected. You may want to try Git Large File Storage — https://git-lfs.github.com.
remote: error: Trace: ***
remote: error: See http://git.io/iEPt8g for more information.
remote: error: File *** is 120.94 MB; this exceeds GitHub’s file size limit of 100.00 MB
To git@github.com:***
 ! [remote rejected] master -> master (pre-receive hook declined)
 ! [remote rejected] *** -> *** (pre-receive hook declined)
error: failed to push some refs to ‘git@github.com:***’

HEAD의 마지막 Commit에는 100MB가 넘는 파일이 없더라도 이전 Commit 중에 100MB 이상의 파일이 포함된 적이 있다면 이 경고를 피할 수 없다. 그러다 보니 게임과 같이 대용량의 Binary 파일을 자주 다루는 프로젝트를 Github에 올릴 때에는 높은 확률로 위 메시지를 만나게 된다.

해결책

다행히도 해결책이 존재한다. 경고 메시지에도 안내되어 있듯이 몇 가지 조처를 해주면 100MB 이상의 파일도 Github에 올릴 수 있다.

1. git-lfs 적용

Commit 과정에서 지정한 파일을 작게 조각내주는 Git extension인 git-lfs — Git Large File Storage https://git-lfs.github.com/ — 를 로컬에 설치한 뒤, 적용하려는 Repository 경로에서 다음 명령을 실행한다.

$ git lfs install
Updated pre-push hook.
Git LFS initialized.

그다음 용량이 큰 파일을 git-lfs의 관리 대상으로 등록해준다. 다음 예시는 120MB 정도의 exe 파일을 Stage에 추가한 상황에서, 확장자가 exe인 모든 파일을 git-lfs의 관리 대상으로 지정하고 Commit을 수행한 모습이다.

$ git lfs track “*.exe”
Tracking *.exe$ git commit -m “Large file included”
[master (root-commit) dd2b715] Large file included
(...)

이제 하단에 있는 3번 과정대로 Github에 push를 시도하면 된다. 그런데 기존에 100MB 이상의 파일을 Commit한 적이 있다면 여전히 100MB 이상의 파일을 올릴 수 없다는 경고 메시지를 보게 된다. 그럴 땐 다음 2번 과정을 적용해야 한다.

2. BFG Repo-Cleaner 적용

기존 Commit에서 100MB보다 큰 파일의 로그를 강제로 없애줘야 한다. BFG Repo-Cleaner — BFG Repo-Cleaner https://rtyley.github.io/bfg-repo-cleaner/ — 를 이용하면 그 작업을 손쉽게 적용할 수 있다.

공식 사이트에서 bfq-x.x.x.jar — x.x.x는 버전 — 를 받고, 대상이 되는 Repository에서 다음과 같이 그동안의 Commit에 포함된 100MB 이상의 파일을 정리하는 명령을 실행한다.

$ java -jar bfg-x.x.x.jar --strip-blobs-bigger-than 100M
(...)
Deleted files
    — — — — — — -
    Filename Git id
    — — — — — — — — — — — — — — 
    ***.exe | c304fcfb (120.9 MB)
(...)

간혹 다음과 같은 오류가 나타날 수 있다.

$ java -jar bfg-x.x.x.jar --strip-blobs-bigger-than 100MUsing repo : C:\***\.gitScanning packfile for large blobs: 132
Scanning packfile for large blobs completed in 13 ms.
Warning : no large blobs matching criteria found in packfiles — does the repo need to be packed?
Please specify tasks for The BFG :
bfg x.x.x
(...)

그럴 땐 아래 명령을 먼저 수행하고 다시 위의 bfg-x.x.x.jar에 의한 명령을 실행한다.

$ git repack && git gc
Counting objects: 3002, done.
(...)

3. git-push 재시도

위 과정들을 적용한 뒤 push를 시도하면 다음과 같이 성공 메시지를 볼 수 있다.

$ git push
Counting objects: 3089, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (1809/1809), done.
Writing objects: 100% (3089/3089), 234.95 MiB | 1.30 MiB/s, done.
Total 3089 (delta 1236), reused 2890 (delta 1229)
To git@github.com:***
 * [new branch] master -> master
 * [new branch] *** -> ***

마치며

개인적으로 Private repository를 무제한으로 만들 수 있다는 점 때문에 Github보다는 Bitbucket을 자주 사용한다. 이번에 큰 용량의 Binary 파일이 있는 프로젝트를 Github의 Private repository에 올릴 일이 있어서 용량 제한 정보를 찾아 봤는데 Github은 개별 파일당 100MB의 제한이 있고 Repository 전체에 대한 용량 제한은 없는 반면, Bitbucket은 개별 파일에 대한 용량 제한은 없지만 Repository당 2GB의 전체 용량 제한이 있다. 따라서 Private repository를 써야할 때 유료 결제가 부담이 안 되는 상황이라면 git-lfs 덕분에 Github을 쓰는 것이 더 효율적인 선택이라고 본다. 물론 전체 크기가 2GB가 넘는 프로젝트가 아니라면 Bitbucket으로 충분하다고 할 수 있겠다.

도움 주신 분

  • jjunCoder님의 제보로 오탈자를 수정했습니다. (2017. 2. 28)

참고자료

  1. Conditions for large files — User Documentation https://help.github.com/articles/conditions-for-large-files/
  2. Git Large File Storage https://git-lfs.github.com/
  3. Removing files from a repository’s history — User Documentation https://help.github.com/articles/removing-files-from-a-repository-s-history/
  4. BFG Repo-Cleaner https://rtyley.github.io/bfg-repo-cleaner/
  5. git repack vs git gc — aggressive http://git.661346.n2.nabble.com/git-repack-vs-git-gc-aggressive-td7564559.html
  6. What kind of limits do you have on repository/file/upload size? — Atlasssian Documentation https://confluence.atlassian.com/bitbucket/what-kind-of-limits-do-you-have-on-repository-file-upload-size-273877699.html

팀 프로젝트를 하다보면

 

기존에 github에서 로그아웃하고

 

다른 계정으로 작업하고 싶은 일이 생길 것입니다.

 

전 이 과정에서 많은 시간을 허비했으므로 (....) 기록을 남깁니다.

 

 

 

 

 

 

그 때 작업을 하는 방법을 포스트 하겠습니다.

 

 

 

 

github에 새 repository를 만들고

 

기존에 하던 방식대로 진행하다보면

 

 

$ git push -u origin master

 

를 하면

 

remote: Permission to newaccount/projectname.git denied to oldaccount.

fatal: unable to access 'https://github.com/newaccount/projectname.git/': The requested URL returned error: 403

newaccount는 현재 계정을

newproject는 현재 업로드하려고 만들어 놓은 repository의 이름을 의미합니다

 

이런 에러가 뜰 것이다.

 

 

 

 

 

 

먼저 git에 등록된 이름과

email을 확인해봅시다.

 

 

 

 

git config user.name

git config user.email

 

을 하면

 

구 계정과 구 이메일이 나올 것입니다.

 

 

 

 

 

 

 

 

git config --global user.name 신계정

git config --global user.email 신이메일

 

로 바꿔주고

 

다시한번 확인해봅시다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

그리고 제어판의 사용자 계정에 들어갑니다.

 

사용자 계정 -> 자격 증명 관리에 들어갑니다.

 

이 곳은 윈도우OS가 관리하는 인증 정보를 보관하는 곳입니다.

github 정보도 여기에서 관리합니다.

 

 

 

 

 

 

 

 

 

 

 

다음 Windows 자격 증명에 들어가면

 

일반 자격 증명 탭에

 

기존에 사용하던 토큰들이 있을 것입니다.

 

git 과 관련된건 지워줍시다.

 

 

 

 

 

 

그리고 업로드 하고 싶은 프로젝트 우클

 

git bash here 클릭

 

 

 

 

 

 

 

 

git init

 

git remote add origin 레파지토리 주소

 

git pull origin master

 

git add .

 

git commit -m "first commit"

 

git push -u origin master

(git add 띄고 . ) (git commit 띄고 -m) (git push 띄고 -u)

 

 

순서대로 합시다.

 

 

 

 

 

 

 

 

그러면 push 하려는 순간

 

새로 로그인 하라는 창이 뜰겁니다.

 

 

 

새 계정과 이메일로 바꿔주고

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

하면 잘 됩니다.

 

 

 

자신의 respository에 들어가보면 잘 된 모습을 확인할 수 있을 것입니다.

 

 

 

수고하셨습니다.

 

https://meaownworld.tistory.com/entry/github-git-bash-%ED%84%B0%EB%AF%B8%EB%84%90-%EA%B3%84%EC%A0%95-%EB%B3%80%EA%B2%BD

<!DOCTYPE html>
<html>
<head>
    <title>오늘 날짜 입력</title>
</head>
<body>
    <input type="text" id="dateInput">
    <script>
        // 오늘 날짜 가져오기
        const today = new Date();
        const year = today.getFullYear();
        const month = String(today.getMonth() + 1).padStart(2, '0'); // 월은 0부터 시작하므로 1을 더하고 두 자리로 포맷팅
        const day = String(today.getDate()).padStart(2, '0'); // 일자를 두 자리로 포맷팅

        // yyyy-mm-dd 형식으로 날짜 문자열 생성
        const formattedDate = `${year}-${month}-${day}`;

        // input 요소에 날짜 설정
        document.getElementById('dateInput').value = formattedDate;
    </script>
</body>
</html>

HTML의 input 요소의 type 속성을 "text"로 설정하고 사용자가 오늘 날짜를 입력할 수 있도록 하려면 JavaScript를 사용하여 오늘 날짜를 가져와서 input 요소의 value 속성에 설정해야 합니다.

이 코드에서는 JavaScript를 사용하여 오늘 날짜를 가져오고, 이 날짜를 "yyyy-mm-dd" 형식의 문자열로 변환한 다음 input 요소의 value 속성에 설정합니다. 결과적으로 input 필드에 오늘 날짜가 표시됩니다.

JavaScript에서 typeof 연산자는 피연산자의 데이터 타입을 문자열로 반환합니다. typeof는 다음과 같은 데이터 타입을 반환할 수 있습니다:

"undefined": 값이 할당되지 않은 변수 또는 존재하지 않는 객체의 속성
"boolean": 참(true) 또는 거짓(false) 값을 가진 불리언 타입
"number": 숫자 타입 (정수 및 실수)
"string": 문자열 타입
"object": 객체, 배열, null 값
"function": 함수 타입
"symbol": 심볼 타입 (ES6부터 추가됨)
typeof 연산자 사용 예시:

console.log(typeof undefined); // "undefined"
console.log(typeof true); // "boolean"
console.log(typeof 42); // "number"
console.log(typeof "Hello, world!"); // "string"
console.log(typeof {}); // "object"
console.log(typeof []); // "object" (배열도 객체로 간주됩니다)
console.log(typeof null); // "object" (null도 객체로 간주됩니다)
console.log(typeof function() {}); // "function"
console.log(typeof Symbol()); // "symbol"
주의할 점은 typeof 연산자가 배열과 null을 "object"로 반환한다는 것입니다. 배열을 구분하려면 Array.isArray() 함수를 사용하면 됩니다.

위 폴더에서 특정 단어를 찾으려면 find 명령어를 사용할 수 있습니다. 다음은 Linux 및 macOS에서 하위 폴더에서 특정 단어를 찾는 방법입니다:

bashCopy code
find /시작경로 -type f -exec grep -l '특정단어' {}
  • /시작경로: 검색을 시작할 디렉토리 경로를 지정합니다. 이것은 검색을 시작할 디렉토리를 나타냅니다. 예를 들어, 전체 시스템에서 검색하려면 /를 사용하고, 현재 디렉토리에서 검색하려면 .를 사용할 수 있습니다.
  • -type f: find 명령을 사용하여 파일만 검색하도록 지정합니다. 디렉토리는 검색에서 제외됩니다.
  • -exec grep -l '특정단어' {} \;: 각 파일에 대해 grep 명령을 실행하여 특정 단어를 찾습니다. -l 옵션은 해당 파일에서 단어를 찾으면 파일의 이름을 출력하도록 지정합니다. {}는 find 명령에서 찾은 각 파일의 이름을 나타냅니다.

예를 들어, 현재 디렉토리부터 하위 폴더에서 "example"라는 단어를 찾으려면 다음 명령을 사용할 수 있습니다:

 
bashCopy code
find . -type f -exec grep -l 'example' {} \;

이 명령은 현재 디렉토리부터 시작하여 모든 하위 폴더에서 "example"라는 단어가 포함된 파일을 찾아 파일 경로를 출력합니다.

https://velog.io/@seokkitdo

1. 삼항조건 연산자(The Ternary Operator)

if .. else 조건문을 한 라인으로 줄여주는 유용한 기법입니다.

기존

const x = 20;
let answer;

if (x > 10) {
    answer = "greater than 10";
} else {
    answer =  "less than 10";
}

축약

const answer = x > 10 ? "greater than 10" : "less than 10";

또한 중첩해서 사용도 가능합니다.

const answer = x > 10 ? "greater than 10" : x < 5 ? "less than 5" : "between 5 and 10";

2. 간략계산법(Short-circuit Evaluation Shorthand)

기존 변수를 다른 변수에 할당하고 싶을 때, 기존 변수가 null, undefined 또는 비어있는 값이 아닌지 확인하고 싶을 수 있습니다. 이 경우에는 보통 긴 if 조건문을 사용하거나 간략계산법을 축약코딩을 사용할 수 있습니다.

기존

if (variable1 !== null || variable1 !== undefined || variable1 !== '') {
     let variable2 = variable1;
}

축약

const variable2 = variable1  || 'new';

믿기지 않으신다면 es6console에 아래 코드를 복사하여 확인해보세요!

let variable1;
let variable2 = variable1  || 'bar';
console.log(variable2 === 'bar'); // prints true

variable1 = 'foo';
variable2 = variable1  || 'bar';
console.log(variable2); // prints foo

variable1에 falsy한 값을 넣을 경우 bar 문자열이 variable2에 할당될 겁니다.

3. 변수 선언

함수를 시작하기 전 변수를 선언하는 것은 좋은 자세입니다. 이 축약기법은 동시에 여러개의 변수를 선언함으로써 시간과 코드라인을 줄일 수 있습니다.

기존

let x;
let y;
let z = 3;

축약

let x, y, z=3;

4. If Presence Shorthand

사소한 것일지 모르나, 알아두면 좋을 것 같습니다. if 조건문을 사용 시 때때로 대입 연산자를 생략할 수 있습니다.

기존

if (likeJavaScript === true)

축약

if (likeJavaScript)

위 두가지 예제가 정확하게 일치하지는 않습니다. 그 이유는 기존방법의 경우 true일 경우에만 조건문을 실행하는 반면 축약기법에서는 truthy 일 경우 통과하도록 되어있기 때문입니다.

다음 예제를 보시면 a가 true가 아닐 경우, 조건문을 실행합니다.
기존

let a;
if ( a !== true ) {
// do something...
}

축약

let a;
if ( !a ) {
// do something...
}

5. 반복문(For Loop)

만약 외부 라이브러리에 의존하지 않고 바닐라 자바스크립트만을 사용하길 원한다면 이 팁은 아주 유용합니다.

기존

const fruits = ['mango', 'peach', 'banana'];
for (let i = 0; i < fruits.length; i++)

축약

for (let fruit of fruits)

단순히 인덱스에만 접근하길 원한다면 다음과 같은 방법도 있습니다.

for (let index in fruits)

또한 리터럴 객체의 키에 접근하려는 경우에도 마찬가지로 동작합니다.

const obj = {continent: 'Africa', country: 'Kenya', city: 'Nairobi'}
for (let key in obj)
  console.log(key) // output: continent, country, city

Array.forEach를 통한 축약기법

function logArrayElements(element, index, array) {
  console.log("a[" + index + "] = " + element);
}
[2, 5, 9].forEach(logArrayElements);
// a[0] = 2
// a[1] = 5
// a[2] = 9

6. 간략 계산법(Short-circuit Evaluation)

기본 값을 할당하기 위해 파라미터가 null 또는 undefined인지 확인하느라 6줄의 코드를 작성하는 것보다 Short-circuit Evaluation 계산법을 이용해 한 줄의 코드로 작성하는 방법이 있습니다.

기존

let dbHost;
if (process.env.DB_HOST) {
  dbHost = process.env.DB_HOST;
} else {
  dbHost = 'localhost';
}

축약

const dbHost = process.env.DB_HOST || 'localhost';

process.env.DB_HOST 값이 있을 경우 이 값을 dbHost에 할당하지만 없다면 localhost를 할당합니다. 이에 대한 정보는 여기 에서 더 살펴볼 수 있습니다.

7. 십진법 지수(Decimal Base Exponents)

0이 많이 포함된 숫자를 적을 때, 이 수많은 0들을 제외하고 숫자를 작성한다면 있어보이지 않을까요? 예를들어 1e7은 10,000,000 과 동일하며 1뒤에 7개의 0이 딸려온 것을 의미합니다.

기존

for (let i = 0; i < 10000; i++) {}

축약

for (let i = 0; i < 1e7; i++) {}

// All the below will evaluate to true
1e0 === 1;
1e1 === 10;
1e2 === 100;
1e3 === 1000;
1e4 === 10000;
1e5 === 100000;

8. 객체 프로퍼티

자바스크립트에서 객체 리터럴 표기법은 코딩을 더 쉽게 만듭니다. ES6 는 객체에 프로퍼티를 할당하는것을 더 쉽게 만들어 주었습니다. 만약 객체의 프로퍼티 이름이 키 이름과 같을 경우에 축약기법을 사용할 수 있습니다.

기존

const x = 1920, y = 1080;
const obj = { x:x, y:y };

축약

const obj = { x, y };

9. 화살표(Arrow) 함수

기존의 함수는 읽고 쓰기가 쉽도록 되어있지만 다른 함수 호출에 중첩하여 사용하게 될 경우 다소 길어지고 헷갈리게 됩니다.
기존

function sayHello(name) {
  console.log('Hello', name);
}

setTimeout(function() {
  console.log('Loaded')
}, 2000);

list.forEach(function(item) {
  console.log(item);
});

축약

sayHello = name => console.log('Hello', name);

setTimeout(() => console.log('Loaded'), 2000);

list.forEach(item => console.log(item));

화살표 함수와 일반 함수의 차이점은 그 생김새로도 확인할 수 있지만 this가 기존 함와 다르게 작동합니다. 따라서 위 두 예제는 완전히 동일한 예제는 아닙니다.
이 차이점에 대해 알고 싶으시다면 여기 를 클릭해주세요.

10. 묵시적 반환(Implicit Return)

return 은 함수 결과를 반환하는데 사용되는 키워드입니다. 한 줄로만 작성된 화살표 함수에서는 return 명령어가 없어도 자동으로 반환하도록 되어있습니다. 다만 중괄호를 생략해야지만 return 키워드도 생략할 수 있습니다.

여러 라인의 코드(객체 리터럴) 를 반환하려면 중괄호 대신 () 를 사용해서 함수를 감싸면 됩니다. 다음과 같이 한 줄로 코드가 작성되었음을 확인할 수 있습니다.

기존

function calcCircumference(diameter) {
  return Math.PI * diameter
}

축약

calcCircumference = diameter => (
  Math.PI * diameter;
)

11. 파라미터 기본값 지정

기존에는 if 문을 통해 함수의 파라미터에 기본 값을 지정해주었지만 ES6 에서는 함수 선언문 자체에 파라미터의 기본 값을 설정해 줄 수 있습니다.
기존

function volume(l, w, h) {
  if (w === undefined)
    w = 3;
  if (h === undefined)
    h = 4;
  return l * w * h;
}

축약

volume = (l, w = 3, h = 4 ) => (l * w * h);

volume(2) //output: 24

12. 템플릿 리터럴(Template Literals)

문자열로 ' + '를 입력하며 자바스크립트 값을 추가하는 손가락 노동에 지치지 않으시나요? 더 쉬운 방법은 없을까요? 만약 ES6 사용하실 줄 안다면 백틱(backtick)을 사용해서 스트링을 감싸고 변수를 ${}로 감싸서 손쉽게 연결 할 수 있습니다.

기존

const welcome = 'You have logged in as ' + first + ' ' + last + '.'

const db = 'http://' + host + ':' + port + '/' + database;

축약

const welcome = `You have logged in as ${first} ${last}`;

const db = `http://${host}:${port}/${database}`;

13. 구조 분해 할당(Destructuring Assignment)

유명한 프레임워크로 개발을 하고 있다면 컴포넌트나 API간 데이터를 전송하기 위해서 객체 리터럴이나 배열로 이뤄진 데이터를 사용하게 될 가능성이 큽니다. 데이터 객체가 컴포넌트에 들어가게 되면, unpack이 필요합니다.

기존

const observable = require('mobx/observable');
const action = require('mobx/action');
const runInAction = require('mobx/runInAction');

const store = this.props.store;
const form = this.props.form;
const loading = this.props.loading;
const errors = this.props.errors;
const entity = this.props.entity;

축약

import { observable, action, runInAction } from 'mobx';

const { store, form, loading, errors, entity } = this.props;

추가적으로 커스텀 변수명을 지정할 수 있습니다.

const { store, form, loading, errors, entity:contact } = this.props;

위의 코드는 구조분해할당을 통해 entity를 가져오고 난 후 contact라는 변수명을 지정한 겁니다.

14. 여러줄로 문자열 쓰기

한 줄 이상의 문자열을 입력하게 될 경우가 있다면 기존의 방법보다 훨씬 편한 방법이 있습니다.

기존

const lorem = 'Lorem ipsum dolor sit amet, consectetur\n\t'
    + 'adipisicing elit, sed do eiusmod tempor incididunt\n\t'
    + 'ut labore et dolore magna aliqua. Ut enim ad minim\n\t'
    + 'veniam, quis nostrud exercitation ullamco laboris\n\t'
    + 'nisi ut aliquip ex ea commodo consequat. Duis aute\n\t'
    + 'irure dolor in reprehenderit in voluptate velit esse.\n\t'

아래와 같은 방법으로 백틱(backtick)을 사용하는 방법도 있습니다.

축약

const lorem = `Lorem ipsum dolor sit amet, consectetur
    adipisicing elit, sed do eiusmod tempor incididunt
    ut labore et dolore magna aliqua. Ut enim ad minim
    veniam, quis nostrud exercitation ullamco laboris
    nisi ut aliquip ex ea commodo consequat. Duis aute
    irure dolor in reprehenderit in voluptate velit esse.`

15. 전개 연산자(Spread operator)

ES6 에서 소개된 스프레드 연산자는 자바스크립트 코드를 더 효율적이고 재미있게 사용할 수 있는 방법들을 제시합니다. 간단히는 배열의 값을 변환하는데 사용할 수 있습니다. 스프레드 연산자를 사용하는 방법은 점 세개(...)를 붙이면 됩니다.

기존

// joining arrays
const odd = [1, 3, 5];
const nums = [2 ,4 , 6].concat(odd);

// cloning arrays
const arr = [1, 2, 3, 4];
const arr2 = arr.slice()

축약

// joining arrays
const odd = [1, 3, 5 ];
const nums = [2 ,4 , 6, ...odd];
console.log(nums); // [ 2, 4, 6, 1, 3, 5 ]

// cloning arrays
const arr = [1, 2, 3, 4];
const arr2 = [...arr];

concat() 함수와는 다르게 스프레드 연산자는 배열 내부의 원하는 위치 어디에나 추가할 수 있습니다.

const odd = [1, 3, 5 ];
const nums = [2, ...odd, 4 , 6];

스프레드 연산자는 또한 ES6 의 구조화 대입법(destructuring notation)와 함게 사용할 수도 있습니다.

const { a, b, ...z } = { a: 1, b: 2, c: 3, d: 4 };
console.log(a) // 1
console.log(b) // 2
console.log(z) // { c: 3, d: 4 }

16. 필수(기본) 파라미터(Mandatory Parameter)

기본적으로 자바스크립트 함수의 파라미터값을 받지 않았을 경우, undifined로 지정합니다. 몇몇 다른 언어들은 에러 메시지를 나타내기도 합니다. 이런 기본 파라미터는 강제로 할당하는 방법은 if문을 사용해서 undefined일 경우 에러가 나도록 하거나,
Mandatory Parameter를 사용하는 방법이 있습니다.

기존

function foo(bar) {
  if(bar === undefined) {
    throw new Error('Missing parameter!');
  }
  return bar;
}

축약

mandatory = () => {
  throw new Error('Missing parameter!');
}

foo = (bar = mandatory()) => {
  return bar;
}

17. Array.find

자바스크립트로 특정 값을 찾기 위한 함수를 작서앟다보면 보통 for 루프를 이용해서 접근을 하곤 합니다. 그러나 ES6 에서 find()라는 새로운 함수가 생겼습니다.

기존

const pets = [
  { type: 'Dog', name: 'Max'},
  { type: 'Cat', name: 'Karl'},
  { type: 'Dog', name: 'Tommy'},
]

function findDog(name) {
  for(let i = 0; i<pets.length; ++i) {
    if(pets[i].type === 'Dog' && pets[i].name === name) {
      return pets[i];
    }
  }
}

축약

pet = pets.find(pet => pet.type ==='Dog' && pet.name === 'Tommy');
console.log(pet); // { type: 'Dog', name: 'Tommy' }

18. Object [key]

Foo.bar를 Foo['bar'] 로 적을 수 있다는 걸 알고 있으신가요? 왜 후자와 같이 코딩을 해야 하는지 의문이 들 수도 있지만, 재사용이 용이한 코드 블락을 작성하기 위해서는 매우 효율적인 방법입니다.
아래의 간단한 validation 함수를 확인해보세요

기존

function validate(values) {
  if(!values.first)
    return false;
  if(!values.last)
    return false;
  return true;
}

console.log(validate({first:'Bruce',last:'Wayne'})); // true

위 함수로 validation 기능을 완벽하게 사용할 수 있습니다. 하지만 form 요소들과 validation 옵션으로 사용해야하는 영역과 규칙이 많을 경우 위 함수는 점점 복잡해지고 길어지게 됩니다. 이를 방지하기 위해서 실행시 옵션을 부과할 수 있는 포괄적인 validation함수를 작성하는 방법을 알아보겠습니다.

축약

// object validation rules
const schema = {
  first: {
    required:true
  },
  last: {
    required:true
  }
}

// universal validation function
const validate = (schema, values) => {
  for(field in schema) {
    if(schema[field].required) {
      if(!values[field]) {
        return false;
      }
    }
  }
  return true;
}


console.log(validate(schema, {first:'Bruce'})); // false
console.log(validate(schema, {first:'Bruce',last:'Wayne'})); // true

위의 예시처럼 사용한다면 모든 form에 공통으로 적용할 수 있는 validation 함수를 작용할 수 있습니다.

19. 단항 비트 논리부정 연산자 (Double Bitwise NOT)

비트 연산자는 자바스크립트를 처음 배울 때를 제외하고는 한 번도 적용해 본 적 없는 연산자일 겁니다. 애당초 이진법으로 코딩하지 않는다면 1과 0을 사용 할 일이 없죠.

하지만 단항 비트 논리부정 연산자를 효율적으로 사용할 수 있는 방법을 알려드립니다.
바로 Math.floor() 함수의 대체용으로 사용할 수 있다는 것이죠. 또 Math.floor()함수보다 훨씬 빠르게 작동한다는 장점도 있습니다. 단항 비트 논리부정 연산자에 대해서는 여기 에서 더 알아보실 수 있습니다.

기존

Math.floor(4.9) === 4  //true

축약

~~4.9 === 4  //true

20. 거듭제곱(Exponent Power)

Math.pow를 통해 거듭제곱을 나타낼 수 있습니다.

기존

Math.pow(2,3); // 8
Math.pow(2,2); // 4
Math.pow(4,3); // 64

축약

2**3 // 8
2**4 // 4
4**3 // 64

21. 문자열 숫자 변환

때때로 필요한 데이터는 숫자 형식이어야 하는데 문자열 타입이 오는 경우가 있을 수 있습니다. 하지만 이러한 타입변환은 손쉽게 해결할 수 있습니다.

기존

const num1 = parseInt("100");
const num2 =  parseFloat("100.01");

축약

const num1 = +"100"; // converts to int data type
const num2 =  +"100.01"; // converts to float data type

'study > Front' 카테고리의 다른 글

java script 오늘날짜 입력  (0) 2023.10.25
Javascript typeof. typeof undefined  (0) 2023.10.25
find  (0) 2023.10.24
formData axios selectbox  (0) 2023.10.16
axios.js  (0) 2023.10.16
<select id="flag">
    <option value="1">선택</option>
</select>

특정 value 값의 선택을 true시킴
$("#flag").val("1").prop("selected", true);

전체 삭제 Just..
$("select#아이디 option").remove();


$('#selectBox option:selected').val();            // select box 선택 값 출력
$('#selectBox option:selected').text();           // option 값 출력


특정 옵션 삭제
$("select#아이디 option[value='option']").remove();


옵션 추가
$("select#아이디").append("<option value='option'>옵션추가</option>");


<input type="checkbox" name="ckall">
<input type="checkbox" name="ck">
<input type="checkbox" name="ck">

$("input[name=ckall]").click(function(){
    if($("input[name=ckall]").prop("checked")){
        $("input[name=ck]").prop("checked",true);   // 전체 체크
    }else{
        $("input[name=ck]").prop("checked",false);  // 전체 체크 해제
    }
});

var chkArray = new Array();

$("input:checkbox[name='delCheck']:checked").each(function(){
    chkArray.push($(this).closest('tr').data('revolutionSeq'));
});

 

인텔리제이 코드정렬

command + option + shift + L 누른후 ok

 

var formData = new FormData(); // Currently empty
formData.append(name, value);
formData.append(name, value, filename);
생성자
FormData()
새로운 FormData 객체를 생성합니다.

메소드
FormData.append()
FormData 객체안에 이미 키가 존재하면 그 키에 새로운 값을 추가하고, 키가 없으면 추가합니다.

FormData.delete()
FormData 객체로부터 키/밸류 쌍을 삭제합니다.

FormData.entries()
이 객체에 담긴 모든 키/밸류 쌍을 순회할 수 있는 iterator를 반환합니다.

FormData.get()
FormData 객체 내의 값들 중 주어진 키와 연관된 첫번째 값을 반환합니다.

FormData.getAll()
FormData 객체 내의 값들 중 주어진 키와 연관된 모든 값이 담긴 배열을 반환합니다.

FormData.has()
FormData 객체에 특정 키가 포함되어 있는지 여부를 나타내는 boolean 을 반환합니다.

FormData.keys()
이 객체에 담긴 모든 키/벨류 쌍들의 모든 키들을 순회 할 수 있는 iterator를 반환합니다.

FormData.set()
FormData 객체 내에 있는 기존 키에 새 값을 설정하거나, 존재하지 않을 경우 키/밸류 쌍을 추가합니다.

FormData.values()
이 객체에 포함된 모든 밸류를 통과하는 iterator를 반환합니다.


let formData = new FormData();

// ... formData.append("키이름", "값"); 생략

for (let key of formData.keys()) {
	console.log(key, ":", formData.get(key));
}

for(let value of formData.values()){
	console.log(value, " : ",formData.get(value));
}

 

<template>
  <div>
    <form v-on:submit.prevent="submitForm"> 
      <div>
        <label for="username">id:</label>
        <input id="username" type="text" v-model="username">
      </div>
      <div>
        <label for="password">pw:</label>
        <input id="password" type="password" v-model="password">
      </div>
      <button type="submit">login</button>
    </form>
  </div>
</template>

<script>
import axios from 'axios'

export default {
  data: function(){
    return {
      username: '',
      password: '',
    }
  },
  methods: {
    submitForm: function() {
      
      console.log(this.username, this.password);
      var url = 'https://jsonplaceholder.typicode.com/users';
      var data = {
        username: this.username,
        password: this.password
      }
      axios.post(url, data)
        .then(function(response){
        console.log(response);
       })
        .catch(function(error){
          console.log(error);
        });
    }
  }
}
</script>

엑시오스(axios)

'study > Front' 카테고리의 다른 글

java script 오늘날짜 입력  (0) 2023.10.25
Javascript typeof. typeof undefined  (0) 2023.10.25
find  (0) 2023.10.24
모르면 손해보는 21가지 JavaScript 축약코딩 기법seokkitdo·2021년 12월 31일  (0) 2023.10.20
axios.js  (0) 2023.10.16
let tmpDt = "empty";
    fn_get_corp_cd=function(){
    axios({
       method: 'get', //통신 방식
       url: '/logs/getCORP_CD', //통신할 페이지
       data: {} //인자로 보낼 데이터
    })
    .then(response=>{
       console.log('console responseData',response);
       tmpDt = response;
       return tmpDt;
    })
    .catch(error=>{
       //console.log(error);
       tmpDt = error;
       return tmpDt;

    })


    $("#corpcdselect").empty();
    $("#corpcdselect").append(htm)


}
function resolveAfter2Seconds() {
    return new Promise((resolve) => {
       setTimeout(() => {
          resolve(tmpDt);
       }, 2000);
    });
}

async function asyncCall() {
    console.log('calling');
    const result = await axios.post('/logs/getCORP_CD').then(response=>{
          console.log(response)
          });

    console.log("result2 ",result);
    const result2 = await axios.post('/logs/getCORP_CD').then(res=>{
       console.log(res)
    });

    // Expected output: "resolved"
}

 TestApiCall = async function(){
    try {
       const response = await axios.post('/logs/getCORP_CD')
       console.log("response >>", response.data)
       const response2 = await axios.post('/logs/getCORP_CD')
       console.log("response >>", response2.data)
    } catch(err) {
       console.log("Error >>", err);
    }
}

 

 

axios.js
0.06MB

+ Recent posts