웹개발하면 CORS에러 겪음
CORS가 필요한 배경인 SOP를 먼저 알아보자
Same-Origin Policy의 준말, 동일 출처 정책을 뜻함
즉 같은 출처의 리소스만 공유가 가능하다는 정책
여기서 출처는 다음과 같다.
출처는 프로토콜, 호스트, 포트의 조합인데 이중 하나라도 다르면 동일한 출처로 보지 않는다. 심지어 http:// https://도 다른것
SOP는 해킹등 위협에서 더 안전해지기 위해 만들어짐, 타 사이트와의 리소스공유를 제한함
하지만 다른출처의 리소스를 사용하고 싶을때는 어쩌지?
Cross-Origin Resource Sharing
교차 출처 리소스 공유, 현 출처에서 실행중인 웹 어플이 다른 출처의 선택한 자원에 접근하는 권한을 부여하도록 브라우저에 알려주는 체제
크게 세가지 동작방식을 가짐
1. 프리플라이트 요청(Preflight Request)
실제 요청을 보내기 전, Option메서드로 사전 요청을 보내 해당 출처 리소스에 접근권한이 있는지 확인하는 것
응답헤더의 Acces-Control-Allow-Origin으로 돌아오면 실제 요청을 보내게됨
요청보낸 출처가 접근권한이 없다면 CORS에러 띄움
미리 권한확인 할수있어 실제요청을 통째로 보내는것보다 리소스측면에서 효율적
단순요청
특정조건이 만족되면 프리플라이트 요청 생략하고 요청보내는것
인증정보를 포함한 요청
요청 헤더에 인증정보를 담아 보내는 요청, 프론트, 서버 양측 모두 CORS설정이 필요함
const http = require('http');
const server = http.createServer((request, response) => {
// 모든 도메인
response.setHeader("Access-Control-Allow-Origin", "*");
// 특정 도메인
response.setHeader("Access-Control-Allow-Origin", "https://codestates.com");
// 인증 정보를 포함한 요청을 받을 경우
response.setHeader("Access-Control-Allow-Credentials", "true");
})
const cors = require("cors");
const app = express();
//모든 도메인
app.use(cors());
//특정 도메인
const options = {
origin: "https://codestates.com", // 접근 권한을 부여하는 도메인
credentials: true, // 응답 헤더에 Access-Control-Allow-Credentials 추가
optionsSuccessStatus: 200, // 응답 상태 200으로 설정
};
app.use(cors(options));
//특정 요청
app.get("/example/:id", cors(), function (req, res, next) {
res.json({ msg: "example" });
});
http요청을 처리하고 응답을 보내주는 프로그램을 웹 서버라 부름
이번에는 웹 서버를 만듭니다
터미널창에 node server/basic-server.js 치면
로컬호스트:5000으로 서버에 접속할수있다
get요청(브라우저에 그냥 치기)을 해볼수있다
localhost:5000/upper
if(메소드가 options) 프리프라이트리퀘스트 즉 cors설정을 돌려줘야 한다.
if(메소드가 post, url이 /upper면) 대문자로 응답을 돌려줘야한다
else if (메소드 post, url /lower) 소문자로 응답을 돌려줘야 한다
else 에러로 처리한다. 404 bad request
const http = require('http');
const server = http.createServer((request, response) => {
// 여기서 작업이 진행됩니다!
});
이 서버로 오는 HTTP 요청마다 createServer에 전달된 함수가 한번씩 호출된다.
const http = require('http');
const PORT = 4999;
const ip = 'localhost';
const server = http.createServer((request, response) => {
if(request.method === 'OPTIONS') { //CORS
response.writeHead(200, defaultCorsHeader);
response.end();
}
if(request.method === 'POST' && request.url === '/upper'){
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString().toUpperCase();
response.writeHead(200, defaultCorsHeader);
response.end(body);
});
}
else if(request.method === 'POST' && request.url === '/lower'){
let body = [];
request.on('data', (chunk) => {
body.push(chunk);
}).on('end', () => {
body = Buffer.concat(body).toString().toLowerCase();
response.writeHead(200, defaultCorsHeader);
response.end(body);
});
}
else {
response.writeHead(404, defaultCorsHeader);
response.end();
}
console.log(
`http request method is ${request.method}, url is ${request.url}`
);
});
server.listen(PORT, ip, () => {
console.log(`http server listen on ${ip}:${PORT}`);
});
const defaultCorsHeader = {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Accept',
'Access-Control-Max-Age': 10
};
[버퍼,버퍼,버퍼,버퍼]
형태가 돼/ 1
// console.log(this); => window
// 2
// function a() {
// console.log(this); => window
// }
// a();
// 3
const obj = {
b: function () {
console.log(this); => obj
},
};
// obj.b();
// 4
// addEventListener => e.target
// 5
// class => 해당 클래스의 인스턴스
// 동적으로 변하는 this 고정 => bind
const a = function () {
console.log(this);
};
a();
const b = a.bind({ d: 1234 });
b();
this암기한다 > bind를통해서 this고정 > 클래스, 프로토타입