배경 이미지
728x90
반응형

 

show/hide 

기본적으로 요소를 숨김/표시할 때, display를 사용

See the Pen Untitled by 김두희 (@ctpfpijl-the-looper) on CodePen.

 

다만  display는 transition 속성에 영향을 받지 않기 때문에 자연스러운 애니메이션 구현이 안됨..!

 

fade in/fade out

자연스러운 fade in/fade out 애니메이션을 구현하려면 display 대신 visibility 사용

visibility는 transition  속성에 영향을 받음

See the Pen Untitled by 김두희 (@ctpfpijl-the-looper) on CodePen.

 

 

 

opacity 속성만을 사용하여 요소를 숨기게 되면, 요소는 여전히 DOM에서 차지하는 공간을 유지하고, 마우스 클릭 등의 이벤트도 발생할 수 있음. opacity를 0으로 설정하면 요소가 완전히 투명해지지만, 요소의 공간과 이벤트는 그대로 유지 됨.

 

728x90
반응형
728x90
반응형

 

문제 상황

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>iPad</title>
    <script defer type="module" src="./js/main.js"></script>
</head>
<body>
   
</body>
</html>

위와 같은 html 파일을 로컬환경에서 크롬 브라우져로 실행시켰더니

 

다음과 같이 에러 발생

 

에러 메시지 설명

Access to script at 'file:///C:/경로/js/module.js'  from origin 'null' has been blocked by CORS policy: Cross origin requests are only supported for protocol schemes: http, data, isolated-app, chrome-extension, chrome, https, chrome-untrusted.

  • file://: 로컬 파일 시스템에서 로드하려고 시도함.
  • origin 'null': 로컬 파일 시스템에서의 출처는 null로 간주됨.
  • CORS policy: 다른 출처의 리소스에 접근할 때 CORS 정책에 의해 차단됨.
  • 지원되는 프로토콜: http, https, data 등 프로토콜을 통해서만 접근이 허용됨.

왜?

매번 'CORS 란게 있구나' 정도로 넘어갔기 때문에 이번 기회에 제대로 한번 알아봐야 겠다고 생각.

일단 핵심은 브라우저 보안 정책인 동일 출처 정책(SOP) 때문

 

동일 출처 정책 (SOP):란?

브라우저는 보안을 위해 동일 출처 정책(Same-Origin Policy, SOP)을 사용함.

이 정책은 한 출처(origin)에서 불러온 문서나 스크립트가 다른 출처에서 불러온 리소스와 상호작용하는 것을 제한함.

이를 통해 악성 스크립트가 사용자의 데이터를 훔치거나 변경하는 것을 방지하기 위함.

이때 출처를 구분하는 기준은 URI의 `프로토콜, 호스트, 포트`가 같은가를 통해 구분한다.

 

참고) 일반적인 HTTP(S) URL의 구성 요소

예: http://www.example.com:80/path/to/file.html

protocol host (port) resource
http:// www.example.com (:80) /folder/file.html

 

로컬 파일 시스템의 경우

예:  file:///C:/경로/js/module.js

protocol host (port) resource
file null null C:/경로/js/module.js

로컬 파일 시스템에서 file:// 프로토콜을 사용할 때는 프로토콜이 file로 고정되고,

호스트와 포트가 없기 때문에 출처가 null로 간주된다.

 

! 여기서 드는 의문 !

근데 여기서 사용한 html 파일과  html에서 불러온 JavaScript  파일은 둘다 파일 시스템에서 로드된  동일 출처 인데, 왜 CORS 오류 나는 거임?

HTML과 JavaScript 파일 로드 차이점

  1. HTML 파일 로드:
    • 브라우저는 로컬 파일 시스템(file:// 프로토콜)에서 HTML 파일을 열 수 있습니다.
    • HTML 파일은 다른 리소스(이미지, CSS, JavaScript 등)를 포함할 수 있습니다.
  2. JavaScript 파일 로드:
    • HTML 파일이 <script> 태그를 통해 JavaScript 파일을 로드하려고 할 때, type="module"이 없는 경우에는 일반 스크립트로 처리됨
      • 일반 스크립트는 로컬 파일 시스템에서 문제없이 직접 로드할 수 있으며, 상대적으로 덜 엄격한 보안 정책이 적용  
    • type="module" 속성이 있는 경우에는 ES6 모듈로 처리되어 CORS 정책이 적용됨. 
      • 모듈 스크립트는 CORS 정책을 따르기 때문에 file:// 프로토콜을 사용할 때 문제가 발생
      • 브라우저는 보안상의 이유로 로컬 파일 시스템에서 직접 모듈 스크립트를 로드하는 것을 차단함
      • 이로 인해 CORS 오류가 발생하며, null 출처에서 다른 리소스를 로드할 수 없슴

즉,

<script  src="./js/main.js"></script>

이렇게 쓰면 문제가 안됨

<script  type="module" src="./js/main.js"></script>

type="module" 쓰는 경우 CORS 정책 적용

왜 같은  JavaScript인데  type="module" 속성이 있는 경우에만 CORS 정책이 적용되는가?

  • 모듈 스크립트는 ES6 모듈의 특성상, 다른 모듈을 가져오기 위해 네트워크 요청을 사용한다. 이를 통해 브라우저는 더 엄격한 보안 정책을 적용하여, 동일 출처 정책(Same-Origin Policy, SOP)을 강제함.

 

type="module" 쓰고 싶은데 해결 방법은?

로컬 서버 사용하면 됨 ㅇㅇ

그러면 로컬 파일 시스템 대신 로컬 서버를 사용하여 파일을 제공함

쉽게 말해 로컬 서버에서 올려 `프로토콜, 호스트, 포트`를 같게 만들어 CORS 에러를 해결함. 

 

어떻게?!

http-server , live-server  등 여러가지 로컬 서버들 중에 골라서 사용하면 됨!

npm install -g http-server
or
npm install -g live-server

 

터미널 창에서 위와 같은 명령어를 통해 전역으로 설치

http-server
or
live-server

이후에는 해당 명령어만으로 로컬 서버를 실행할 수 있음. 기본적으로 8080 포트에서 실행

 

 

요약

  • 문제: type="module"을 사용한 스크립트가 로컬 파일 시스템에서 열릴 때 CORS 오류 발생.
  • 이유: 브라우저 보안 정책인 동일 출처 정책(SOP) 때문.
  • 해결책: 로컬 서버를 사용하여 파일을 제공. Node.js의 http-server를 사용하여 간단히 로컬 서버를 설정할 수 있다.

 

 

 

 

 

 

 

 

728x90
반응형

'Vanilla JS' 카테고리의 다른 글

[Vanilla JS] Intersection Observer API  (0) 2024.07.26
728x90
반응형

1. 기본 선택자

전체 선택자 (Universal selector)

html의 모든 요소에 적용

* {
    color: red;
}

 

타입 선택자 (Type selector)

특정 태그 이름을 가진 모든 요소를 선택

h1 {
	color: red;
}

 

클래스 선택자 (Class selector)

주어진 class명을 가진 모든 요소를 선택

.title {
	color: red;
}

 

ID 선택자 (ID selector)

id 속성에 맞는 요소를 선택

#title {
	color: blue;
}

 

속성 선택자 (Attribute selector)

주어진 속성을 가진 모든 요소를 검색 

 

특정 속성을 가진 요소 선택

  • 문법: [attribute]
  • 예제: title 속성을 가진 모든 요소를 선택
[title] {
    color: blue;
}

 

특정 값을 가진 속성을 선택

  • 문법: [attribute="value"]
  • 예제:  title 속성이 'example'인 요소를 선택
[title="example"] {
    color: blue;
}

 

특정 값을 포함하는 속성을 선택

  • 문법: [attribute~="value"]
  • 예제: class 속성에 'header' 단어가 포함된 요소를 선택
[class~="header"] {
    color: blue;
}

 

 

 

2. 복합 선택자 

 

일치 선택자 (태그와 클래스)

태그와 클래스를 동시에 만족하는 요소를 선택

 

<span class="orange">오렌지</span>

span.orange {
    color: red;
}

후손 선택자

자신이 포함하고 있는 모든 요소 중에서 선택

<div>
    <span class="orange">오렌지</span>
</div>

div .orange {
    color: red;
}

 

자식 선택자 

해당 태그의 자식 요소 중에서 선택

<ul>
    <li class="orange">오렌지</li>
</ul>

ul > .orange {
    color: red;
}

 

 인접 형제 선택자 

다음 형제 요소를 한 개 선택

<ul>
    <li class="orange">오렌지</li>
    <li>사과</li>
</ul>

.orange + li {
    color: red;
}

 

일반 형제 선택자 

다음 형제 요소를 모두 선택

<ul>
    <li class="orange">오렌지</li>
    <li>사과</li>
    <li>망고</li>
</ul>

.orange ~ li {
    color: red;
}

 

728x90
반응형

+ Recent posts