본문 바로가기
Front-end/Browser

직접 서버를 만들면서 배운 Location Header

by ciocio 2021. 10. 26.

✔  Location  :  <url>

 

Location Response header는 "re-direct" 할 url을 명시한다.

3XX(redirection) 이나 201(created) 상태 코드가 응답되었을 때만 적용할 수 있다.

3XX 상태코드가 반환되었을 때, 기존 url에 Location에 명시된 url을 붙여 완성된 새로운 URL에 request를 보낸다 ! (fetch 요청) 

 

📎  303 See Other 상태 코드

언제나 GET 메서드를 사용해 re-direct fetch 요청을 보낸다. (기존의 original 메서드 무시)

PUT 이나 POST 메서드가 요청된 이후에 변경된 상황을 "읽고싶을 때" 주로 사용한다.

 

📎  307 Temporary Redirect 상태 코드

기존의 original 메서드를 변경하지 않고, 동일한 메서드로 re-direct fetch 요청을 보낸다. (일시적으로 방문한다)

re-direct된 요청이 만들어질 때 기존 메서드와 payload는 변경되지 않는다.

 

📎  308 Permanent Redirect 상태 코드

기존의 original 메서드를 변경하지 않고, 동일한 메서드로 re-direct fetch 요청을 보낸다.  (영구적으로 머문다)

re-direct된 요청이 만들어질 때 기존 메서드와 payload는 변경되지 않는다.

브라우저가 re-direct fetch 요청에 대한 응답을 받아오면(페이지를 불러오면) 검색 엔진은 해당 링크를 resource에 업데이트한다.

 

📎  301 Moved Permanently 상태 코드

명시적으로는 메서드 변경이 금지되어있다.  (예측이 어려움)  re-direct fetch 요청을 보낸다.  (영구적으로 머문다)

GET 메서드나 HEAD 메서드에 대한 응답으로만 사용하고, POST 메서드일땐 308 상태 코드를 이용하는 편이 좋다.

브라우저가 re-direct fetch 요청에 대한 응답을 받아오면(페이지를 불러오면) 검색 엔진은 해당 링크를 resource에 업데이트한다.

 

📎  302 Found 상태 코드

명시적으로는 메서드 변경이 금지되어있다.  (예측이 어려움)  re-direct fetch 요청을 보낸다.  (일시적으로 방문한다)

GET 메서드나 HEAD 메서드에 대한 응답으로만 사용하고, POST 메서드일땐 307 상태 코드를 이용하는 편이 좋다.

브라우저가 re-direct fetch 요청에 대한 응답을 받아오면(페이지를 불러오면) 검색 엔진은 해당 링크를 resource에 업데이트하지않는다.

 

📍  아니, 308 이랑 301 이랑 같고, 307 이랑 302 랑 같은 거 아냐 ? 뭐 이리 복잡해 ??

 

308과 301, 307과 302 서로서로 너무 비슷하다. 하지만 !! 진짜 큰 차이점이 하나 있다.

308과 307은 redirection 요청을 보낼 때 메서드와 바디가 변경되지 않기때문에 신뢰성이 보장되지만,

301과 302는 변경하지 않는 것이 원칙이지만, 예측불허 메서드를 GET으로 변경해 redirection 요청을 보낼 때가 있다.

308, 307 불변 에측 가능. 301, 302 불변 예측 불가능.

그래서 GET이나 HEAD 메서드로 re-direct fetch 요청 보낼 때만 301이나 302를 쓰라고 권고하는 것이다.

(예측 불허한 경우의 수마저 범주 안에 있으니까 ... 정확하게 쓰고싶으면 307이나 308 써야지 ^_^)

 

 

📌  서버 만들기

 

◾  App.js

 

const express = require('express');
const cors = require('cors');
const app = express();
const port = 3001;

const bookRouter = require('./router/bookRouter');

app.use(express.json());
app.use(cors());

app.use('/book', bookRouter);

app.use((req, res, next) => {
  res.status(404).send('Not Found!');
});

app.use((err, req, res, next) => {
  res.status(500).send({
  	message: 'Internal Server Error',
    stacktrace: err.toString()
  });
});

app.listen(port, () => {
  console.log(`http://localhost:${port}`)
});

module.exports = app;

 

◾  bookRouter.js

 

const express = require('express');
const router = express.Router();

const { findById, create } = require('../controller/bookController');

router.get('/', findById);

router.post('/', create);

module.exports = router;

 

◾  bookController.js

 

const flights = require('../repository/flightList');
const _ = require('lodash');

let booking = [];

module.exports = {
  
  findById: (req, res) => {
    
    const book = booking.filter(item => _.isMatch(item, req.query));
    
    if(req.query.phone){
      return res.status(200).json(book[0]);
    }
      return res.status(200).json(book);
    
  },
  
  create: (req, res) => {
  	
    let query = '?';
    let keys = Object.keys(req.body);
    
    booking.push(req.body);
    
    keys.forEach(key => {
      query += `${key}=${encodeURIComponent(req.body[key])}&`
    });
    
    // 처음에 query += `${key}=${req.body[key]}` 로 query를 구성해줬는데
    // 한글 자체를 query string에 넣어주니 오류가 났었다.
    // {
    //    "message": "Internal Server Error",
    //    "stacktrace": "TypeError [ERR_INVALID_CHAR]: 
    //                   Invalid character in header content [\"Location\"]"
    // }
    // 그래서 모든 키 값들을 (url들을) 인코딩시켜 query string 을 구성해주었다.
    
    return res.status(301)
             .header('Location', `${query.slice(0, -1)}`)
             .json({book_id: `${booking.length - 1}`});
    
    // 303 을 써줬을 때 당연히 POST -> GET 요청 차례대로 잘 간다.-> 무조권 re-direct 메서드는 GET
    // 301, 302 을 써줬을 때 POST -> GET 요청이 차례대로 잘 갔다.-> user-agent가 오래됐나 ..?
    // 307, 308 을 써줬을 때 POST 에서 error가 발생한다. 
    // -> 무한 POST 메서드 redirection이 갔다는 걸 확인할 수 있다.
    // Error: Exceeded maxRedirects. Probably stuck in a redirect loop 
    // http://localhost:3001/book?uuid=af6fa55c-da65-47dd-af23-578fdba44bed&
    // name=%ED%99%8D%EA%B8%B8%EB%8F%99&phone=010-1234-5678
    
  }
  
};

 

 

📌  Postman 이용해서 request / response 확인

 

 

POST 요청에 대한 응답에 있는 Location Header의 url로 GET 요청을 보내고 응답을 받은 걸 확인할 수 있다.

 

✔  POST

 

 

✔  GET

 

 

 

📌  느낀점

 

계속해서 브라우저를 타고타고타고타고타고타 들어갈 때 유용한 헤더같다.

아직은 PUT이나 POST 메서드가 요청된 후 결과값이 들어있는 url을 반환하는 정도 ...? 에 머물러있는 것 같다.

이 메서드를 정확히 어떻게 쓰는 지 알고싶다 !  ->  지금은 Location의 동작과정을 알기 위해 억지로 로직을 짠 느낌이기에 ㅎ

또한 Location header에서는 url을 건내줄 때, 보통 params를 넘겨주는지 query를 넘겨주는지도 궁금하다. 

반응형

댓글