본문 바로가기

자바스크립트(jquery)

javascript input 데이터 post 전송 제한

반응형

꽤나 많은 input 데이터들을 저장해야하는 일이 있었다.

평소에 하듯이 ajax 로 직렬화를 한 후 post로 데이터를 넘기는데 큰 이상이 없었는데 데이터를 확인해보니 일정 이상 input 데이터가 들어오지 않고 짤려있었다.

특별한 오류도 화면에 나오지 않았던터라 문제없는줄 알았으나 아니였던 것...

 

일단 확인해볼것은 메모리 문제

사실 메모리문제면 처리하는 동안 화면도 멈출테고 완료 메세지도 return이 되지 않겠지만 확인해보면 결과 역시 메모리문제는 아니였다. memory limit를 무한대로 줘도 그대로였다.

 

두번째로는 POST 용량제한 

다른 언어는 모르겠다만 작업한 php에서는 post 로 받아올때 용량제한이 걸려있다. 사실 이것도 warning이 뜨는것으로 알고있었으나 혹시나 하는 마음에 확인해본결과

post max size가 800M 로 되어있었는데 사실 웹에서 저 용량은 채워 보내기엔... 무리가 있다.

애초에 저정도 채우려면 웹페이지 자체가 거의 멈춘다.

 

세번째로는 CLOB으로 들어간 문자열 길이가 너무길다?

였는데 이 문제역시 post max size로 귀결되며 문제없었다.


 

여러 삽질을 해본 결과... 문제는 max_input_vars 였다.

기본적으로 php에서는 max_input_vars 이 1000 으로 설정되어있다.

max_input_vars란 input으로 받는 변수의 수를 제한하는 설정인데 이게 걸렸던 것 이다.

오류도 뜨지않아 파악하기 힘들었다.

 

작업한 페이지가 input 박스가 사실상 무제한으로 늘어날 수 있는 형태이기에 문제가 생겼던 것이다.

 

해결을 해보려고 할 때 가장 먼저 생각난건 max_input_vars 값을 늘리는 거였지만 사실상 임시방편일 뿐이고 서버 공격에 취약해진다.

Hash Dos 공격에 노출된다는건데

간단하게 대규모 파라미터를 이용하여 공격하는것이다.

https://blog.naver.com/PostView.naver?blogId=wnrjsxo&logNo=221360964753&parentCategoryNo=&categoryNo=2&viewDate=&isShowPopularPosts=false&from=postView

Hash Dos에 대해 설명해둔 블로그...

 

진짜로 해결해보자

다수의 input 데이터가 직렬화되어 각각의 name을 가지고 post로 넘어가는게 문제

고로 이 데이터를 ajax로 넘기기 전 하나의 객체로 만들고 넘기면 된다.

let jsonDataArray = [];
$('div[id^=div_]').each(function(){

    var inputs = $(this).find("input");
    var selects = $(this).find("select");

    // div 요소에 속한 input 요소를 순회
    var inputJsonArray = [];
    inputs.each(function() {
        var inputName = $(this).attr('name');
        var inputValue = $(this).val();

        if(inputName=='undefined' || inputName==undefined){
            return;
        }

        // JSON 객체 생성 후 배열에 추가
        var inputJson = {};
        inputJson[inputName] = inputValue;
        inputJsonArray.push(inputJson);
    });

    selects.each(function() {
        var selectName = $(this).attr('name');
        var selectValue = $(this).val();

        if(selectName=='undefined' || selectName==undefined){
            return;
        }
        // JSON 객체 생성 후 배열에 추가
        var selectJson = {};
        selectJson[selectName] = selectValue;
        inputJsonArray.push(selectJson);
    });

    jsonDataArray.push(inputJsonArray);

});

// jsonDataArray를 문자열로 변환하여 PHP로 전송
let jsonData = JSON.stringify(jsonDataArray);

$.ajax({
    	type:"POST"
    	,async:false
    	,dataType:"json"
	,data: {"jsonData": jsonData}
        /*
        이하생략
        */
});

이런식으로 json의 배열형식으로 만든 후 하나의 문자열로 만들어서 전송했다.

 

솔직히 웹화면에서 1000개 이상의 input 데이터를 넘기는 일이 많지는 않겠다만

있을수 있으니 기억해두자