폼포나치 유리막 세정제입니다.
셀프세차 할 때 시간도 많이 걸리고 힘들어서 구매했는데 사용법은 간단합니다.

사용법 : https://youtu.be/PQ-YeyjeNdA

제품 및 분사노즐 2개, 드라이버(캡 제거용), 타올 2개 배송됐네요.

 

아직 사용해 보진 않았는데
셀프세차가 기다려지네요~








모니터

 

 

최근 우리나라에 알려진 퀀트바인, 퀀트바인 코인에 대해 주의가 필요하여 글을 작성합니다.

1. https://quantvine.net
2. https://quantvines.top
3. https://quantvine.co.kr
3. https://quantvine.kr (2025/02/10 호스팅 폐쇄)


1. 초기 투자금 필요
초기 투자금 테더(USDT)를 입금해야 가능하다. 상한선, 하한선을 정해놨지만 레벨을 올리면 얼마든지 투자금은 늘어날 수 있다.


2. 엄청난 수익률
퀀트바인 사이트에 접속하면 일 1.8%~ 이상의 수익률로 돈을 벌 수 있다고 홍보하지만 단순 계산만으로도 연 600%가 넘는 수익률인데 그런 좋은 방법이 있는데 왜 본인들이 안하고 다른 사람들에게 알려줄까?
수수료(3%~9%)를 받고 할 수 있지만 일 1.8%를 벌 수 있는데 그깟 수수료 벌려고 할까?  AI시대에 이런 비지니스 모델은 세상에 알려지면 copy는 순식간이다.


3. 회사
미국에서 유명 핀테크 회사라 홍보는 하는데 회사 주소가 없다. (캘리포니아주 샌프란시스코에서 시작했단 말만...)


홈페이지 하단에 Terms of Service, Privacy Policy를 클릭해 보면 중국 사이트로 연결된다.
    - http://cs.epepe.cn/terms-of-service/
    - http://cs.epepe.cn/


4. 도메인
회사 소개 글에 보면 2021년도에 회사가 설립된 것으로 나오는데 도메인 생성일자가 최근 우리나라에서 퀀트바인이 알려지기 시작 바로 전인 2024년 10월초에 생성됐다.
도메인의 종료일자도 너무 짧다. (잘 나가는 회사는 도메인을 10년단위로 생성)

- quantvine.net
    - 생성일자 : 2024-10-01
    - 만료일자 : 2026-10-01


- quantvines.top
    - 생성일자 : 2024-09-28
    - 만료일자 : 2026-09-28


- quantvine.co.kr
    - 생성일자 : 2024-10-23
    - 만료일자 : 2025-10-23


5. 트랜드
구글 트랜드에 quantvine을 확인하면 회사가 있는 미국에서는 알려지지도 않고
라이베리아, 토고, 대한민국, 아제르바이잔에서만 검색이 되고 있으며, 얼마전까지만 해도 대한민국에서 관심도가 1위였다.



6. 앱 (App)
앱 다운로드 시 구글/애플 스토어가 아닌 설치파일(apk)을 직접 다운로드 한다.
스토어에 올리지 못하는 이유는 뭘까? (앱은 절대 다운받아 설치하지 말자)




# 결론
최근에 블로그, SNS 등 퀀트바인에 가입하여 테더( USDT )를 입금하고 원금 출금까지 했다며 자랑(?)이라고 쓴 인증글들이 보인다.
폰지 사기는 당연히 초기에 돈을 버는 사람이 존재하며 사이트에 입금액보다 출금액 증가량이 미미해지거나 적어진다면 사이트는 언제든지 폐쇄 될 것이다.

  • 점점 출금 기간이 오래 걸리다든지, 출금이 막힐 수 있다.
  • 수익금을 QVC 코인으로 대체하여 줄 수 있다.



"나만 아니면 돼"라는 마인드로 주변에 홍보하고 인터넷에 글을 올리는 사람들은 자신을 다시 돌아봤으면 좋겠다.

 

1. Maven 프로젝트 구성 후 아래 처럼 오류가 발생하는 경우

 

Description	Resource	Path	Location	Type
cvc-elt.1.a: Cannot find the declaration of element 'project'.	pom.xml	/mvn	line 1	Language Servers

Description	Resource	Path	Location	Type
Downloading external resources is disabled.	pom.xml	/mvn	line 3	Language Servers


# 방법1

오류 부분을 마우스 over하면 나오는 tooltip에서 "Force download of 'https://maven.apache.org/xsd/maven-4.0.0.xsd'" 링크를 클릭하면 자동 다운로드 됨




# 방법2
https => http 로 변경

# 기존
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">

# 변경
<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">







출처 : https://noritersand.github.io/java/2013/12/05/java-%EC%9E%90%EB%B0%94-%EB%A6%AC%ED%94%8C%EB%A0%89%EC%85%98-reflection/

관련 문서



리플렉션이란 인스턴스로 클래스의 정보를 분석하기 위한 기법이면서, 자바에서 해당 기법을 구현한 클래스와 패키지의 통칭이다.

변수의 이름을 파라미터로 다루기

public class Test {
    String person1 = "사람1";
    String person2 = "사람2";

    public static void main(String[] args) throws Exception {
        Test test = new Test();
    }
    void getValue(String who) throws Exception {
        System.out.println("show something..");
    }
}


일반적으로는 다음처럼 가장 간단하고 고전적인 방식인, 비교에 의한 분기문으로 구현할 수 있을것이다:



String 타입의 인스턴스 변수인 person1, person2가 선언되어 있는 클래스가 있다. 그리고 그 필드의 값을 파라미터에 따라 선택하여 출력하는
 getValue() 메서드를 구현한다고 하자.

void getValue(String who) throws Exception {
    if (who.equals("person1")) {
        System.out.println(this.person1);
    } else if (who.equals("person2")) {
        System.out.println(this.person2);
    }
}


만약 분기문을 사용하지 않고 Field 클래스를 이용해 변수명을 문자열로 취급하려면 다음처럼 작성한다:

import java.lang.reflect.Field;

public class Test {
    String person1 = "사람1";
    String person2 = "사람2";

    public static void main(String[] args) throws Exception {
        Test test = new Test();
        test.getValue("person2");
    }

    void getValue(String who) throws Exception {
        Class<?> cls = this.getClass();
        Field person = cls.getDeclaredField(who);
        System.out.println(person.getName()); // person2
        System.out.println(person.get(this)); // 사람2
    }
}
Test test = new Test();
Field target = test.getDeclaredField("내가 찾아야 할 녀섴");


인스턴스의 클래스값을 getClass로 가져와 getDeclaredField 메서드를 이용하면 해당 필드에 관한 정보를 가져올 수 있다.

target.get(test);


이 정보는 Field 클래스 타입이며 여기서 getName 혹은 get을 이용하면 프로퍼티의 이름과 값을 구할 수 있다. 여기서 get메서드의 인자값으로는 같은 타입의 인스턴스 객체를 넘겨줘야한다.

setAccessible()

public void setAccessible(boolean flag)

setAccessible()은 필드나 메서드의 접근제어 지시자에 의한 제어를 변경한다.

일반적으로 private 인스턴스 변수나 메서드는 해당 클래스의 외부에서는 접근할 수 없다. 가령 다음처럼 private으로 지정된 some 변수에 접근하려고 하면 예외가 발생할 것이다.

class AccessTest {
    private String some = "yo";
    private String getSome() {
        return this.some;
    }
}

public class MainClass {
    public static void main(String[] args) throws Exception {
      AccessTest accessTest = new AccessTest();

      System.out.println(accessTest.some); // compile error: The field AccessTest.some is not visible

      Field field = accessTest.getClass().getDeclaredField("some");
      System.out.println("field: " + field.get(accessTest));
      /*
       * runtime error:
       *     java.lang.IllegalAccessException:
       *     Class MainClass can not access a member of class AccessTest with modifiers "private"
       */
    }
}

이때 setAccessible(true)를 사용하면 문제 없이 접근할 수 있게 된다:

class AccessTest {
    private String some = "yo";
    private String getSome() {
        return this.some;
    }
}

public class MainClass {
    public static void main(String[] args) throws Exception {
      AccessTest accessTest = new AccessTest();

      Field field = accessTest.getClass().getDeclaredField("some");
      field.setAccessible(true);
      System.out.println("field: " + field.get(accessTest));

//    System.out.println(accessTest.some); // 이것은 여전히 불가능하다.

      Method method = accessTest.getClass().getDeclaredMethod("getSome");
      method.setAccessible(true);
      System.out.println("method: " + method.invoke(accessTest, (Object[]) null));

//    System.out.println(accessTest.getSome()); // compile error: The method getSome() from the type AccessTest is not visible

      method.setAccessible(false);
      System.out.println("method: " + method.invoke(accessTest, (Object[]) null));
      /*
       * setAccessible(false)는 접근제어를 원래 상태로 돌려놓기 때문에 다음과 같은 런타임 에러가 발생할 것이다.
       * runtime error:
       *     java.lang.IllegalAccessException:
       *     Class PrivateVariableAcc can not access a member of class AccessTest with modifiers "private"
       */
    }
}

단, 이 방법은 reflect를 통한 필드나 메서드 접근에 한하며 접근연산자(.)를 통한 방식은 불가능하다.

example

import java.lang.reflect.Field;
import java.lang.reflect.Method;

import org.junit.Assert;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ReflectionTest {
    @SuppressWarnings("unused")
    private static final Logger log = LoggerFactory.getLogger(ReflectionTest.class);

    @Test
    public void test() throws Exception {
        Object instance = new MyClass();
        Class<?> clazz = instance.getClass();

        // invoke method
        Method method = clazz.getDeclaredMethod("myMethod");
        Assert.assertNotNull(method);
        Assert.assertEquals("finally you found me!", method.invoke(instance));

        // access field
        Field field = clazz.getDeclaredField("myField");
        Assert.assertNotNull(field);
        Assert.assertEquals(0, field.get(instance));
    }
}

class MyClass {
    public int myField = 0;

    public String myMethod() {
        return "finally you found me!";
    }
}



출처 : http://zero-gravity.tistory.com/270

참고 : http://www.happyjung.com/lecture/2471


집에 서버를 구성하고나서 불과 며칠이 지나지 않아 로그인 시도가 7천번 가까이 있었다. ㄷㄷ

   /var/log/secure로 접속 아이피를 찾아서 조회해보니 죄다 중국쪽으로 찍힌다..;; 우회한 건지 직접 접속 시도한 건지는 모르겠지만... 중국 정말 싫다 ......




   앗 뜨거 하고, 이래선 안되겠다는 생각에 바로 보안 설정에 들어갔다.



   1. SSH 포트 & 프로토콜 변경


vi /etc/ssh/sshd_config


# If you want to change the port on a SELinux system, you have to tell

# SELinux about this change.

# semanage port -a -t ssh_port_t -p tcp #PORTNUMBER

#

Port 1234

#AddressFamily any

#ListenAddress 0.0.0.0

#ListenAddress ::


   Port 부분을 22에서 다른 번호로 변경한다.


# The default requires explicit activation of protocol 1

Protocol 2


   Protocol을 2로 변경한다. (보안상 2로 하는 게 좋다고 한다.)




   2. root로 로그인이 불가능하도록 설정


#LoginGraceTime 2m

PermitRootLogin no

#StrictModes yes

MaxAuthTries 6

#MaxSessions 10


   PermitRootLogin을 주석 해제하고 no로 기입하면 root로는 직접 로그인이 불가능하다. root로 로그인하고 싶다면, 일반 유저로 로그인한 뒤에 "su - root"로 바꿔줘야 함.


   MaxAuthTries는 로그인 시도 횟수를 제한한다. 6으로 해놓을 경우, 6번 로그인 실패하면 자동으로 차단.



   # systemctl reload sshd.service


   설정을 마치고 SSH 서비스를 재시작한다.



# firewall-cmd --permanent --zone=public --add-port=1980/tcp

# firewall-cmd --reload


   마지막으로 1234포트 방화벽 열어주면, 1234 포트로만 SSH 접속이 가능할 것이다.





   만약 되지 않는다?


   내 경우, 여기까지 했는데 포트가 바뀌지 않았다. ㅡㅡ; 그래서 이것저것 찾아본 결과... 뭔가 더 해줘야 했다.


   내껀 semanage로 SSH 포트를 변경해줘야 완벽하게 변경이 됐다.


   CentOS를 최소 설치를 하면 "semanage" 명령어가 실행되지 않는데,


# yum install policycoreutils-python


   이럴 땐, policycoreutils-python을 설치해준다.



# semanage port -a -t ssh_port_t -p tcp 1234


   그리고나서 semanage 명령어로 SSH 포트를 아까 변경해줬던 포트 번호로 설정한다.



# semanage port -l | grep ssh


   위 명령어로 확인해보면 22번 포트가 1234로 잘 변경됐음을 확인할 수 있다.



# systemctl restart sshd.service


   다시 ssh서비스 재시작을 해주면 완료!





   3. Fail2ban 설치 (로그인 시도 아이피 차단)


   Fail2ban은 SSH 로그인 시도가 일정 수 이상일 경우 자동으로 차단해주는 녀석이다. 얼른 설치하자!


# yum install fail2ban jwhois



   설치만 한다고 해서 다 되는 건 아니고, 몇 가지 설정이 필요하다.


# vi /etc/fail2ban/jail.conf


# External command that will take an tagged arguments to ignore, e.g. <ip>,

# and return true if the IP is to be ignored. False otherwise.

#

# ignorecommand = /path/to/command <ip>

ignorecommand =     #123.111.0.444/24 이런식으로 아이피를 적어놓으면 접근 시도를 몇 번을 하든 차단되지 않는다.


# "bantime" is the number of seconds that a host is banned.

bantime  = 600    #일정 횟수를 초과하여 접근 시도 시, 접근 거부 시간. 600초


# A host is banned if it has generated "maxretry" during the last "findtime"

# seconds.

findtime  = 600    #입력한 시간 사이에 지정 횟수 초과 시 차단. 600초


# "maxretry" is the number of failures before a host get banned.

maxretry = 3    #최대 접근 횟수. 3회를 초과할 경우 접근 차단.


# Provide customizations in a jail.local file or a jail.d/customisation.local.

# For example to change the default bantime for all jails and to enable the

# ssh-iptables jail the following (uncommented) would appear in the .local file.

# See man 5 jail.conf for details.

#

# [DEFAULT]

# bantime = 3600

#

 [sshd]

enabled = true  #이걸 true로 해줘야 SSH 접근 시도 시, fail2ban이 동작함.

#

# See jail.conf(5) man page for more information


   설정을 마쳤으면,



# service fail2ban start


   서비스 재시작. 끝!



출처 : http://egloos.zum.com/einmong/v/5885619

UniteTTC-20100221_TTC폰트에서TTF추출.zip


- 사용법

# ttc 에서 ttf 추출

$> UniteTTC gulim.ttc
$> UniteTTC batang.ttc


# ttf 파일을 ttc로 묶음
$> UniteTTC gulim.ttc gulim001.TTF gulim002.TTF gulim003.TTF gulim004.TTF
$> UniteTTC batang.ttc batang001.TTF batang002.TTF batang003.TTF batang004.TTF


※ c:/windows/fonts 에서 ttc 파일에 포함되어 있는 폰트
gulim.ttc : 굴림(001), 굴림체(002), 돋움(003), 돋움체(004)
batang.ttc : 바탕(001), 바탕체(002), 궁서(003), 궁서체(004) 



[구글 어스의 메뉴 및 부가창 폰트 - 아리따 돋움]


이유도 방법도 여러가지가 있습니다. 생각날 때(화면의 저 굴림/돋움 폰트 좀 없애버리고 싶다고 느낄 때) 마다 검색 해 보고 또 따라 해 보기도 했지만, 여러가지 이유로 다시금 원상복귀시키곤 했습니다. 그러던 중 우연히 "사실 굴림체를 없애는 방법은 아주 간단합니다."라는 글을 보고, 방법을 정리해 둡니다.

굴림(체), 바탕(체) 폰트는 폰트 폴더(C:\Windows\Fonts)에 .ttc파일 형태로 제공되어 있습니다. 이는 하나의 파일에 복수의 폰트를 제공하기 위해 사용되는 TTF폰트 컬렉션 파일입니다.

- batang.ttc 파일에는 가변폭 글꼴인 바탕, 궁서, 고정폭 글꼴인 바탕체, 궁서체, 이렇게 4개의 TTF파일이 포함되어 있습니다.
- gulim.ttc 파일에는 가변폭 글꼴인 굴림, 돋움, 고정폭 글꼴인 굴림체, 돋움체 , 이렇게 4개의 TTF파일이 포함되어 있습니다.

적당한 고정폭 글꼴(특히, 셰리프 폰트)은 찾기가 어려워, 바탕은 바탕, 궁서 2종을 "아리따-부리"로, 굴림은 굴림, 돋움 2종을 "아리따-돋움"으로 바꿨습니다. 아래 보이는 UltraISO 스크린샷 처럼, 굴림으로 표기되는 프로그램들의 변화를 확인할 수 있습니다.

- Gulim & GulimChe & Dotum & DotumChe (TrueType) : gulim.ttc

- Batang & BatangChe & Gungsuh & GungsuhChe (TrueType) : batang.ttc

[# 1] 사용 도구

1) UniteTTC (TTC파일에서 TTF파일을 추출해주고, TTF파일 여러개를 TTC파일로 만들어 줍니다)
2) ttfname3 (TTF파일의 폰트 정보를 XML로 추출해주고, 추출한 폰트 정보를 다른 TTF파일에 덮어 씌워 줍니다)

[# 2] 사용 방법

UniteTTC
- TTF추출 : UniteTTC [추출할 폰트.TTC]
- TTC제작 : UniteTTC [생성할 폰트.TTC] [합칠 폰트1.TTF] [합칠 폰트2.TTF] ...

굴림 글꼴 모음 파일(gulim.ttc)에서 TTF 추출
- UniteTTC gulim.ttc
변경 완료된 폰트를 TTC파일로 제작
- UniteTTC gulim.ttc gulim001.TTF gulim002.TTF gulim003.TTF gulim004.TTF

TTFName
- TTF파일의 폰트 정보 추출 : ttfname3.exe [정보를 추출할 폰트.TTF] -o [저장될 정보 파일.XML]
- 정보파일을 원하는 폰트에 입히기 : ttfname3.exe [정보를 입힐 폰트.TTF] [폰트 정보파일.XML] -o [생성될 폰트.TTF]

추출한 굴림폰트(TTF)에서 폰트 정보를 추출. 굴림폰트(TTF)의 정보파일(XML)이 생성됨
- ttfname3.exe gulim001.TTF -o gulim001.xml
추출한 정보파일(XML)을 아리따-돋움 폰트(TTF)에 씌워 새로운 TTF파일 생성
- ttfname3.exe AritaDotumMedium.ttf gulim001.xml -o gulim001.ttf

[# 3] 다운로드

1. UniteTTC (2010.02.21) UniteTTC.zip
http://yozvox.web.fc2.com/556E697465545443.html

2. TTFName (3.0.2.0) TTFName 3.0.2.0.zip 

[# 4] TTF 추출

굴림 글꼴그룹(gulim.ttc)파일을 UniteTTC를 이용해 해체하면 gulim001.TTF / gulim002.TTF / gulim003.TTF / gulim004.TTF의 4개의 파일이 생성됩니다. 2, 4번 글꼴은 고정폭 글꼴인 굴림체와 돋움체입니다.

UniteTTC gulim.ttc

여기서는 가변폭 글꼴인 1번(굴림), 3번(돋움)의 정보를 추출합니다. ttfname을 이용해 gulim001.xml, gulim003.xml을 추출/생성합니다.

ttfname3.exe gulim001.TTF -o gulim001.xml
ttfname3.exe gulim003.TTF -o gulim003.xml


[# 5] TTF 생성

기존의 굴림, 돋움 TTF 폰트(gulim001.TTF, gulim003.TTF)는 삭제하고 아리따-돋움(AritaDotumMedium.ttf)폰트에 xml파일은 씌워 새로운 gulim001.TTF, gulim003.TTF를 생성합니다. 굴림, 돋움 모두 아리따-돋움으로 대체합니다.

del gulim001.TTF
del gulim003.TTF
ttfname3.exe AritaDotumMedium.ttf gulim001.xml -o gulim001.ttf
ttfname3.exe AritaDotumMedium.ttf gulim003.xml -o gulim003.ttf


[# 6] TTC 생성

기존의 굴림 글꼴그룹(gulim.ttc)파일을 삭제하고, 변경된 TTF파일로 새로운 TTC파일 생성합니다.

del gulim.ttc
UniteTTC gulim.ttc gulim001.TTF gulim002.TTF gulim003.TTF gulim004.TTF


[# 7] 시스템의 굴림 폰트 제거

아래와 같은 방법으로 윈도우 상의 (기존에 설치된) 굴림 폰트를 제거할 수 있습니다. (원본 파일은 C:\에 이동 저장)

takeown /F %windir%\Fonts\gulim.ttc /A
icacls %windir%\Fonts\gulim.ttc /grant Administrators:F
move %windir%\Fonts\gulim.ttc C:\


[# 8] 굴림 폰트 설치 & 폰트 캐시 제거 & 리부팅

새롭게 만든 굴림폰트(gulim.ttc)를 설치한 후, FNTCACHE.DAT파일을 제거, 리부팅을 하면 완벽하게 적용됩니다.

del C:\Windows\System32\FNTCACHE.DAT

구글어스의 메뉴폰트 바꾼게 제일 시원합니다.


Polyfill

홈페이지 : https://polyfill.io


- 특정 기능이 지원되지 않은 브라우저를 위해 사용할 수 있는 코드 조각이나 플러그인을 말함. Polyfill은 HTML5 및 CSS3를 사용하는데 있어 오래된 브라우저 사이의 간격을 메꾸는 역할을 함

자동으로 로드되는 polyfill : https://cdn.polyfill.io/v2/docs/
        

아래처럼 polyfill 을 로드하면 브라우저에 맞는 스크립트가 출력된다. 크롬이나 파이어폭스가 로딩하면 코드는 거의 없고 IE에서 로드하면 코드가 많이 나온다.

<!-- 브라우저 환경에 맞게 자동으로 스크립트 로딩 -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>

<!-- 브라우저에 상관없이 전체 소스 로딩 -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=default|always"></script>

<!-- Promise 만 로딩 -->
<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=Promise|always"></script>



HTML5 Cross Browser Polyfills
Modernizr 측에서 정리하여 제공하고 있는 각종 폴리필 목록을 참고하면 원하는 기술을 선택하는데 도움이 될 것이다.

html5shiv : HTML5의 섹셔닝 요소(예: <header>, <nav>)를 지원하지 않는 브라우저를 위한 라이브러리
mediaelement.js : HTML5의 <video>와 <audio> 요소들을 모든 브라우저에서 하나의 파일로 같은 UI를 제공하기 위한 라이브러리
Placeholder : HTML5의 플레이스홀더(placeholder)의 지원을 통일하기 위해서 제공하는 라이브러리
h5Validate : HTML5의 폼검증 기능을 구현하기 위해 제공하는 라이브러리
selectivizr : CSS3의 의사 클래스(pseudo-class)와 속성 선택자들을 IE6~8에서 지원하기 위한 라이브러리
css3pie : CSS3의 border-radius와 box-shadow, liner-gradient를 IE6~9 브라우저에서 지원하기 위한 라이브러리
Respond : 반응형 웹의 필수 속성중에 하나인 미디어쿼리를 IE6~8에서 지원하기 위한 라이브러리

더 많은 polyfill : https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills



Modernizr
- 사용자의 브라우저가 현재 가지고 있는 HTML5, CSS 기능들을 감지하고 지원여부를 판별하는 Javascript 라이브러리 임. 다양한 브라우저에서 지원되는 기능을 하나씩 확인해가면서 개발하는 것은 현실적으로 불가능하기 때문에 Modernizr와 같은 라이브러리를 통해 필요기능을 감지하고 지원 여부에 따라 개발자가 동적으로 처리를 달리할 수 있음

홈페이지 : https://modernizr.com/
Github : https://github.com/Modernizr/Modernizr


========================================================================================================

Object doesn't support property or method 'assign'

IE Object.assign 오류 시 polyfill

if (!Object.assign) {
Object.defineProperty(Object, 'assign', {
            enumerable: false,
    configurable: true,
    writable: true,
    value: function(target) {
    'use strict';
    if (target === undefined || target === null) {
    throw new TypeError('Cannot convert first argument to object');
    }
    var to = Object(target);
    for (var i = 1; i < arguments.length; i++) {
    var nextSource = arguments[i];
    if (nextSource === undefined || nextSource === null) {
    continue;
    }
    nextSource = Object(nextSource);
    var keysArray = Object.keys(Object(nextSource));
    for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
    var nextKey = keysArray[nextIndex];
    var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
    if (desc !== undefined && desc.enumerable) {
    to[nextKey] = nextSource[nextKey];
    }
    }
    }
    return to;
    }
});
}


출처 : https://chanspark.github.io/2017/07/13/%ED%81%AC%EB%A1%AC-%EC%9E%90%EB%8F%99%EC%99%84%EC%84%B1-%EA%B8%B0%EB%8A%A5-%EC%A0%9C%EA%B1%B0%ED%95%98%EA%B8%B0.html


회원가입, 로그인 폼에는 꼭 패스워드와 아이디, 이름, 주소, 카드번호, 카드 비밀번호 등등 다양한 개인정보를 작성해야하는 페이지가 존재합니다. 구글 크롬은 같은 정보를 여러 사이트에서 쉽게 입력할 수 있도록 자동완성기능(autocomplete)이란것을 지원합니다. 문제는 이 자동완성기능이 사이트에서 필요로 하지 않는 정보까지 포함하고 있기때문에 보안 문제가 많다고 하네요.크롬의 자동완성기능의 보안 문제와 해결법-영문그래서 저는 개인적으로 이 기능을 off 하고 사용하고 있지만 저희 고객분들은 그런 기능을 잘 모르는 분들이 많겠죠!! 그렇다고 일일이 고객분들께 사용하지 말아달라고 부탁할 수도 없는 노릇이고… 하니 사이트에서 자체적으로 이 기능을 block 해버리는 방법을 찾아보게 되었습니다.

방법 1 (X)

input  form autocomplete="off"라는 속성값을 부여합니다.

<input type="text" id="..." name="..." autocomplete="off">

인터넷 익스플로러에서는 이 방법이 먹히지만 크롬과 같은 최신 브라우저에서는 통하지 않습니다. 몇년전에 사용하던 방법이었는데 크롬에서 막아버렸다고 하죠. 사유는 뭐 개발자들이 무분별하게 사용해서 이를 방지하는 차원이라는데… 그냥 없애달라고 ㅠㅠㅠ

방법 2 (X)

방법 1이 안된다면, autocomplete="false" 등으로 바꿔보는 방법도 있습니다.

방법 3 (X)

방법 2도 안된다면… 비밀번호 입력칸에 autocomplete="new-password"라고 입력해서 항상 새로운 비밀번호를 입력받는다는 꼼수를 부릴 수도 있습니다.

방법 4

이쯤 와서 정말 화가나기 시작했습니다. 다른일 해야하는데 이거때문에 시간 질질끌리고…. 몇번 더 구글링한 결과 다른 방법을 찾았습니다!!!

먼저 자동완성 기능이 활성화 되는 시점은 form 이나 전체 페이지에서 처음으로 오는 <input type="password"> 요소를 찾아서 바로 앞에 위치하는 input과 자동완성 기능을 띄워주는 방식입니다. 이를 활용하면, 더미 입력폼을 만들어서 해결할 수 있습니다.

<!--remove autocomplete-->
<input style="display:none" aria-hidden="true">
<input type="password" style="display:none" aria-hidden="true">
<!--remove autocomplete end-->
<!--real input start-->
<input type="text"  autocomplete="false" required>
<input type="password" name="password" autocomplete="new-password">
<!--real input end-->

실제로 저는 이렇게 해서 효과를 봤습니다. 완벽하게는 아니지만 password 전에 위치한 인풋창에는 자동완성 기능이 뜨지 않습니다(제 원래 목표). 여전히 password인풋에는 자동완성 창이 뜨네요… ㅠㅠ

번외 - 모바일 인풋 대문자 입력 방지

모바일(특히 iOS)에서는 인풋에서 입력을 시작하면 첫 글자가 대문자로 입력이 됩니다. 하지만 아이디나 이메일 입력창에서 첫 글자가 대문자인 경우는 드물기 때문에 아래 코드릴 입력하시면 좋습니다. 은근히 UX를 개선하는 방법중 하나랄까..

<input type="email" autocapitalize="off">

참고

관련 문제에 대한 스택오버플로 질문글



+ Recent posts