1 minute read

Intro

  • 오늘은 프론트 엔드 개선 작업을 진행해보았다.

Trouble Shooting

RequestDataTooBig

개요

  • ajax로 파일을 업로드 하는 도중 발생한 오류

원인

  • Django에 기본적으로 설정된 최대 파일 업로드 크기는 2.5MB이다.

해결

  • settings.py에서 DATA_UPLOAD_MAX_MEMORY_SIZE = 5242880 를 추가해주었다.(5242880 = 5MB)

의문 및 해결

  • 여태 잘 보내지다가 왜 ajax로 보내려니 새삼스럽게 최대크기 오류가 발생하는지 궁금해서 조사를 진행했다.

  • 조사 결과, submit과 ajax의 차이점을 간략히 정리해둔 글에서 힌트를 얻을수 있었다.

    • ajax는 파일 ‘만’ 전송하기 때문에 파일 크기 오류가 발생.

    • 반면, submit의 경우 ‘form 전체 데이터’를 전송하기 때문에 크기 제한같은것이 딱히 안걸려있던것.

    • 번외로, ajax는 비동기 방식, submit은 동기 방식이라고 한다.

TooManyFieldsSent

개요

  • RequestTooBig을 해결한 직후 또다시 발생한 파일 전송 오류

원인

  • Django에 기본적으로 설정된 DATA_UPLOAD_MAX_NUMBER_FIELDS는 기본적으로 1000이다.

해결

  • settings.py에서 DATA_UPLOAD_MAX_NUMBER_FIELDS = 10240 을 추가해주었다.

의문 및 해결

  • 저 DATA_UPLOAD_MAX_NUMBER_FILEDS가 무엇인지 조사를 해보았고, Django Docs에서 답을 찾을수 있었다.

  • 서비스 거부 공격의 방법중 하나가 대량의 데이터 패킷을 통신망으로 보내는 것인데, 데이터 패킷의 숫자를 DATA_UPLOAD_MAX_NUMBER_FILEDS를 통해 제한함으로서 어느정도 방어한다는것.

  • 내가 해결한 방식 외에도 DATA_UPLOAD_MAX_NUMBER_FIELDS를 None으로 설정하는 방법 역시 존재했는데, 이렇게 설정한 경우 서비스 거부 공격에 취약해질수 있다고 한다.

  • 이것 역시 submit으로 보낼때는 폼 전체를 보내는것이므로, 딱히 데이터 제한에 걸릴것이 없었나보다.

CSRF token missing or incorrect

개요

  • ajax를 통해 파일 업로드를 시도하던중 발생한 오류

원인

  • submit으로 폼 전체를 보내줄 때에는 {% csrf_token %} 을 통해 csrf토큰을 전송해주었다.

  • ajax로 전송하는 과정에는 csrf 토큰이 빠져있어 발생한 오류.

해결

<script>
  $.ajaxSetup({
    headers: { "X-CSRFToken": '{{csrf_token}}' }
  });
</script>

개념 정리

  • csrf 토큰

    • 참고 글

    • 사용자 세션에 임의의 난수값을 저장하고, 사용자의 요청마다 해당 난수값을 포함시켜 전송.

    • 세션 내에 저장된 토큰과 요청 파라미터에 전달되는 토큰 값이 일치하는지 백엔드에서 검증.

MultiValueDictKeyError

개요

  • ajax를 통해 파일 업로드를 시도하던중 발생한 오류

원인

  • ajax를 통해 실행한 url에서는 request.FILES를 통해 이미지를 꺼내오는 작업이 있었다.

  • 비어있는 request에서 무언가를 꺼내려 하니, 당연히 에러가 발생했고, 비어있는 dict에서 무언가 꺼내려할때 발생하는 MultiValueDictKeyError가 발생한것.

해결

  • MultiValueDictKeyError 발생
    • 내가 key 이름을 다르게 설정했나? 싶어 key 이름 변경
    • 실패
  • 폼 데이터를 직접 봐야겠다고 판단.
  • 백엔드에서 print(request.FILES)로 들어온 request를 확인
    • 아무것도 없는 dict를 확인함.
  • 혹시나 싶어 오류 메시지를 올려보니 The number of GET/POST parameters exceeded settings.DATA_UPLOAD_MAX_NUMBER_FIELDS. 발견.

    • settings.py의 DATA_UPLOAD_MAX_NUMBER_FIELDS를 40960으로 변경.

    • DATA_UPLOAD_MAX_NUMBER_FILEDS 오류만 출력되지 않고 여전히 Request는 비어있음

  • 참고한 글

    • 통상적인 파라미터를 보내는 경우에는 processData 옵션을 삭제. 기본값인 true로 설정하는것이 맞다.

    • 하지만 파일을 보내는 경우에는 해당 옵션을 false로 설정해두어야 하는데, 이부분이 누락된것.

    • ajax 구문에 processData: false를 추가했다.