프로젝트_랜드마크 - 24일차
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 토큰이 빠져있어 발생한 오류.
해결
-
html의 헤더에 다음의 스크립트를 추가했다.
<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
를 추가했다.
-