- ๐ CORS๋?
- ๐ ์ถ์ฒ๋?
- ๐ CORS ๋์ ๋ฐฉ์
- ๐ CORS ํด๊ฒฐ ๋ฐฉ๋ฒ
์น ๊ฐ๋ฐ์ ํ๋ค๋ณด๋ฉด ์ธ์ ๊ฐ ์๋์ ๊ฐ์ ์๋ฌ๋ฅผ ๋ณด๋ ๋ ์ด ์๋ค.
CORS๋ Cross-Origin Resource Sharing์ ์ฝ์์ด๋ค. ํด๋น ๋ฌธ์ฅ์ ์ง์ญํ๊ฒ ๋๋ฉด, "๊ต์ฐจ ์ถ์ฒ ๋ฆฌ์์ค ๊ณต์ ์ ์ฑ "์ด๋ผ ํด์ํ ์ ์๋ค.
์ฌ๊ธฐ์ ๊ต์ฐจ ์ถ์ฒ๋ ์๊ฐ๋ฆฐ ๋ค๋ฅธ ์ถ์ฒ๋ฅผ ์๋ฏธํ๋ค.
์ด๋ ํ ์ฌ์ดํธ๋ฅผ ์ ์ํ ๋, ์ฐ๋ฆฌ๋ URL์ด๋ผ๋ ๋ฌธ์์ด์ ํตํด ์ ๊ทผํ๊ฒ ๋๋ค.
URL์ ์๋์ ๊ฐ์ ๊ตฌ์ฑ์์๋ก ์ด๋ฃจ์ด์ ธ ์๋ค.
์ฌ๊ธฐ์ ์ถ์ฒ๋ ํ๋กํ ์ฝ, ํธ์คํธ ๊ทธ๋ฆฌ๊ณ ํฌํธ๋ฅผ ์๋ฏธํ๋ค.
CORS ์ ๊ทผ ์ ์ด ์๋๋ฆฌ์ค์๋ 3 ๊ฐ์ง ๋ฐฉ์์ด ์๋ค.
Preflight Request๋ ์์ฒญ์ ์๋น ์์ฒญ๊ณผ ๋ณธ ์์ฒญ์ผ๋ก ๋๋๋๋ฐ, OPTIONS ๋ฉ์๋๋ฅผ ํตํด ๋ค๋ฅธ ๋๋ฉ์ธ์ ๋ฆฌ์์ค์ ์์ฒญ์ด ๊ฐ๋ฅํ์ง (์ค์ ์์ฒญ์ด ์ ์กํ๊ธฐ์ ์์ ํ์ง) ํ์ธ ์์
์ ํ ๋ค, ์์ฒญ์ด ๊ฐ๋ฅํ๋ค๋ฉด ์ค์ ์์ฒญ์ ๋ณด๋ด๊ฒ ๋๋ค.
Cross-origin ์์ฒญ์ ์ ์ ๋ฐ์ดํฐ์ ์ํฅ์ ์ค ์ ์๊ธฐ ๋๋ฌธ์ Preflight ์์ฒญ์ ํ๋ค.
Simple Request๋ Preflight Request์ ๋ค๋ฅด๊ฒ ์์ฒญ์ ๋ณด๋ด๋ฉด์ ์ฆ์, cross origin์ธ์ง ํ์ธํ๋ค.
๋ํ, ์๋์ ๊ฐ์ ์กฐ๊ฑด์ ๋ชจ๋ ์ถฉ์กฑํด์ผํ๋ค.
- ๋ฉ์๋๋ GET POST HEAD ์ค ํ๋
- ํค๋๋ Accept, Accept-Language, Content-Language, Content-Type ๋ง ํ์ฉ
- Content-Type ํค๋๋ ๋ค์์ ๊ฐ๋ค๋ง ํ์ฉ
- application/x-www-form-urlencoded
- multipart/form-data
- text/plain
์ธ์ฆ ๊ด๋ จ ํค๋๋ฅผ ํฌํจํ ๋ ์ฌ์ฉํ๋ ์์ฒญ์ด๋ค.
๋ธ๋ผ์ฐ์ ๊ฐ ์ ๊ณตํ๋ ๋น๋๊ธฐ ๋ฆฌ์์ค ์์ฒญ API์ธ XMLHttpRequest ๊ฐ์ฒด๋ fetch API๋ ๋ณ๋์ ์ต์
์์ด ๋ธ๋ผ์ฐ์ ์ ์ฟ ํค ์ ๋ณด๋ ์ธ์ฆ๊ณผ ๊ด๋ จ๋ ํค๋๋ฅผ ๊ธฐ๋ณธ์ ์ผ๋ก ์์ฒญ์ ๋ด์ง ์๊ธฐ ๋๋ฌธ์, credentials ์ต์
์ ๋ณ๊ฒฝํ์ง ์๊ณ ์๋ cookie๋ฅผ ์ฃผ๊ณ ๋ฐ์ ์ ์๋ค.
์ต์ ์ ์๋์ ๊ฐ์ด ์ธ ๊ฐ์ง๊ฐ ์๋ค.
์๋ฒ์ธก ์๋ต์์ ์ ๊ทผ ๊ถํ์ ์ฃผ๋ ํค๋๋ฅผ ์ถ๊ฐํด์ ํด๊ฒฐํ๋ค.
app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "*"); // ๋ชจ๋ ๋๋ฉ์ธ res.header("Access-Control-Allow-Origin", "https://example.com"); // ํน์ ๋๋ฉ์ธ });
cors ๋ชจ๋์ ์ฌ์ฉํ์ฌ ํด๊ฒฐํ๋ค.
const cors = require("cors"); const app = express(); app.use(cors());
package.json ์ proxy ๊ฐ์ ์ค์ ํ์ฌ proxy ๊ธฐ๋ฅ์ ํ์ฑํ ํ๋ ๋ฐฉ๋ฒ์ผ๋ก ํด๊ฒฐํ๋ค.
{ //... "proxy": "http://localhost:3000" }