본문 바로가기
카테고리 없음

자바스크립트 AJAX (2/2) ResponseHeader, readyState, CORS

by MOOB 2019. 8. 30.

 

XMLHttpRequest.setRequestHeader

XMLHttpRequest.setRequestHeader는 HTTP Request Header의 값을 설정한다. HTTP Request Header는 요청을 보낼 때 필요한 정보(client, cache, 요청 헤더 등)들을 담는다. 때문에 setRequestHeader()open()send()사이에 반드시 붙여 주어야 한다.

// json으로 전송하는 경우
xhr.open('POST', '/users');

// 클라이언트가 서버로 전송할 데이터의 MIME-type 지정
xhr.setRequestHeader('Content-type', 'application/json');

const data = { id: 3, title: 'test', author: 'me'};

xhr.send(JSON.stringify(data));
// escaping untrusted data
// xhr.send(Object.keys(data).map(key => `${key}=${encodeURIComponent(data[key])}`).join('&'));

또한 요청을 보낼 때 Accept를 설정 해 줄 수 있다. 이는 응답 받을 때 어떤 종류의 데이터를 받고싶은지 명시한다.

xhr.setRequestHeader('Accept', 'application/json');

Ajax response

Ajax의 응답 처리 과정은 다음과 같이 이뤄진다.
XMLHttpRequest.send를 통해 서버에 리퀘스트를 전송하면 서버는 응답을 반환하는데, 언제 그 응답이 클라이언트에 도달할지 알 수 없다. 그러므로 다음과 같이 XMLHttpRequest.onreadystatechange를 사용하여 응답을 감지하여 함수를 실행시켜준다. 이 때 변화는 readyState의 프로퍼티의 변경을 의미한다.

// XMLHttpRequest.readyState 프로퍼티가 변경(이벤트 발생)될 때마다 onreadystatechange 이벤트 핸들러가 호출된다.
xhr.onreadystatechange = function (e) {
  // readyStates, XMLHttpRequest의 상태(state)를 반환
  if (xhr.readyState !== XMLHttpRequest.DONE) return;

  // status는 response 상태 코드를 반환(200 : 정상응답)
  if(xhr.status === 200) {
    console.log(xhr.responseText);
  } else {
    console.log('something\'s wrong!');
  }
};

XMLHttpRequest.readyState

  • 0 : open() 메소드 호출 이전 (unsent)
  • 1 : open() 메소드 호출 완료 (opened)
  • 2 : send() 메소드 호출 완료 (headers_received)
  • 3 : 서버 응답 중 (loading)
  • 4 : 서버 응답 완료 (done)

크로스 도메인

만약 어떤 요청을 통해 전달되는 데이터가 같은 도메인 일 경우 문제가 없지만, 다른 도메인일 경우 보안상의 이유로 동일출처 원칙에 의해 차단 될 수 있다. 이것을 우회하기 위한 방법으로는 프록시와 JSONP, Cross-Origin Resource Sharing이있다. 앞의 두개는 잘 안쓰인다.

이 중 CORS의 작동 방법에 대해 알아보자.

CORS

CORS는 HTTP 헤더에 추가적으로 정보를 추가하여 브라우저와 서버가 서로 통신해야함을 알게 하는 방법이다. 2009년에 등록되어 현재 가장 권장되는 앙법이다. 다음은 node.js 기반으로 한 서버의 해결방법이다. (아직 잘 모름)

const express = require('express')
const cors = require('cors')
const app = express()

app.use(cors())

app.get('/products/:id', function (req, res, next) {
  res.json({msg: 'This is CORS-enabled for all origins!'})
})

app.listen(80, function () {
  console.log('CORS-enabled web server listening on port 80')
})

댓글