CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource, TypeError: Router.use() requires a middleware function but got a Object

문제상황(1)

CORS 정책 이해하기

CORS(Cross-Origin Resource Sharing)는 추가 HTTP 헤더를 사용해 한 출처에서 실행중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제이다. 웹 애플리케이션은 리소스가 다른 출처(도메인, 프로토콜, 포트)와 다를때 교차 출처 HTTP 요청을 실행한다.

서버의 index.js 파일을 다음과 같은 상태에서 서버요청을 보냈더니, 콘솔과 네트워크 탭에 위와같은 에러가 발생했다. 'Access-Control-Allow-Origin' 헤더가 응답 리소스에 없어 CORS 정책에 의해 localhost:3000에서 localhost:8080/posts로 보낸 서버요청이 막혔다고 설명한다.

const express = require("express");
const app = express();
const cors = require("cors");
const postsRouter = require("./router/postsRouter");

app.use(express.json({ strict: false }));
app.use(
  cors({
    origin: ["http://localhost:3001"],
    credentials: true,
    methods: ["GET", "HEAD", "PUT", "PATCH", "POST", "DELETE", "OPTIONS"],
  })
);
app.use("/posts", postsRouter);

const PORT = 8080;

let server = app.listen(PORT, () =>
  console.log(`🚀 Server is starting on ${PORT}`)
);
module.exports = server;

http://localhost:8080/posts에 다른 출처인http://localhost:3000 (또는 3001)가 자원을 요청하고 있기 때문에, 즉 다른 origin이므로 서버의 리소스에 접근할 수 있는 권한을 막는다.

그런데, cors 미들웨어에서 cors options에서 origin 속성으로 접근 허용가능한 출처를 적어주면 다른 출처라도 접근이 가능하다.

나의 경우에는 http://localhost:3001로 설정해주었기 때문에 cors 에러가 나면 안됐다,,

원인

코스 에러라고 떴지만 실제로 원인은 다른데 있었다,, 처음에 서버를 실행할때 node index.js로 실행시켜서, 파일을 아무리 변경하고 저장해도 바뀐 파일로 서버가 재실행되지 않은 거였다.

 "scripts": {
    "start": "nodemon index.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  },

원래는 server 폴더 내 package.json의 scripts 부분에 npm start를 하면 nodemon으로 서버를 실행시켜서 파일을 변경하고 저장할때마다 서버가 자동으로 재실행되는데, 애초에 node index.js로 서버를 실행시켜서 코스 옵션을 변경한 내용이 반영되지 않았던 것이다.

해결?

ctrl+C로 실행중이던 서버를 중지하고, npm start로 서버를 재실행했다. 문제가 모두 해결됐다고 생각했는데 콘솔창에 다른 에러가 떴다...


문제상황(2)

에러 내용을 보니 express 미들웨어인 router에서 에러가 발생한 것 같았다.

원인

구글링을 해보니 나와 같은 에러를 겪는 사람이 스택오버플로우에 올린 질문이 있었다. 그래서 문제를 빠르게 해결할 수 있었다.

해결방법

Router 폴더 내 postsRouter.js를 다음과 같이 export를 추가해주니 에러가 해결되었다.

const express = require("express");
const router = express.Router();
const { posts } = require("../controllers/posts");

router.get("/posts", posts);

module.exports = router; //기존에 빠졌던 부분

CORS 에러로 시작했지만 결국 원인은 다른데 있어서 조금 허무하기도 하다. 에러 메시지에서는 CORS를 문제로 출력하고 있어서 그 문제에 더 집중했던 것 같다. 그래도 이번 기회에 CORS 정책에 대해 공부할 수 있었다.

reference

좋은 웹페이지 즐겨찾기