개발 Q&A

제목 다운로드 헬퍼 통해서 파일 다운로드 시, 사파리의 경우, 한글 파일명이 깨지는 현상이 발생하는데
카테고리 PHP
글쓴이 그동안 작성시각 2021/01/18 14:20:47
댓글 : 6 추천 : 0 스크랩 : 0 조회수 : 7634   RSS
안녕하세요, 다운로드 헬퍼 통해서 파일 다운로드 시, 사파리의 경우, 한글 파일명이 깨지는 현상이 발생하는데
몇일째 해결을 못하고 있는데요, 혹시 아시는 분 계실까요?

다운로드 헬퍼 코드 중 브라우저에 따라 처리하는 부분이 있는데, 
else if($safari) <=== 이 부분을 이렇게 저렇게 다해 봤는데 어떻게 처리할지 모르겠네요;;


if ( ! function_exists('force_download'))
{
	function force_download($filename = '', $data = '')
	{
		if ($filename == '' OR $data == '')
		{
			return FALSE;
		}

		// Try to determine if the filename includes a file extension.
		// We need it in order to set the MIME type
		if (FALSE === strpos($filename, '.'))
		{
			return FALSE;
		}

		// Grab the file extension
		$x = explode('.', $filename);
		$extension = end($x);

		// Load the mime types
		if (defined('ENVIRONMENT') AND is_file(APPPATH.'config/'.ENVIRONMENT.'/mimes.php'))
		{
			include(APPPATH.'config/'.ENVIRONMENT.'/mimes.php');
		}
		elseif (is_file(APPPATH.'config/mimes.php'))
		{
			include(APPPATH.'config/mimes.php');
		}

		// Set a default mime if we can't find it
		if ( ! isset($mimes[$extension]))
		{
			$mime = 'application/octet-stream';
		}
		else
		{
			$mime = (is_array($mimes[$extension])) ? $mimes[$extension][0] : $mimes[$extension];
		}
	  
	    //http_user_agent로 edge인지, ie인지, kakaotalk 인지 여부.
	    $edge = isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'Edge') !== false);   //엣지
	    $ie = isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE') !== false || strpos($_SERVER['HTTP_USER_AGENT'], 'Trident') !== false);  //익스플로러
            $safari = isset($_SERVER['HTTP_USER_AGENT']) && (strpos($_SERVER['HTTP_USER_AGENT'], 'Safari') !== false);   //사파리

	    if($edge)
	    { 
	        //파일명 rowurlencode로 인코딩.
	        $filename = rawurlencode($filename);     
	        $filename = preg_replace('/\./', '%2e', $filename, substr_count($filename, '.') - 1);
	        //헤더 변경
	        $header_cachecontrol = 'private, no-transform, no-store, must-revalidate';
	        $header_pragma='no-cache';
	    }
	    else if($ie)
	    {
            //헤더 변경
            $filename = iconv('utf-8', 'euc-kr', $filename);                          //UTF-8에서 euc-kr로 변경
            $header_cachecontrol = 'must-revalidate, post-check=0, pre-check=0';
            $header_pragma='public';
	    }     
	    //사파리에서 한글 파리명이 꺠지는 문제를 해결 못함. 현재는 깨진 이름으로 다운받아지도록 놔둠.
	    else if($safari)
	    {
            ///////// 이 부분을 이렇게 저렇게 다해 봤는데도 안되네요;; 
	    }
        else  //위 조건들이 아닌 경우,일반 헤더 적용
        {
            $header_cachecontrol = 'private, no-transform, no-store, must-revalidate';
            $header_pragma='no-cache';
        }

	    //적용될 header. 위 브라우저별로 변수를 받아서 대입,적용.
	    header('Content-Type: "'.$mime.'"');
	    header('Content-Disposition: attachment; filename="'.$filename.'"');
	    header('Expires: 0');
	    header('Cache-Control: "'.$header_cachecontrol.'"');
        header("Content-Transfer-Encoding: binary");
	    header('Pragma: "'.$header_pragma.'"');
	    header("Content-Length: ".strlen($data));
	   exit($data);
	}
}

 

===== 다운로드 컨트롤러 ===

	//파일 다운로드
	public function word_file_download()
	{
        if(!$_SERVER['HTTP_REFERER'])
        {
            alert('비정상적인 접근입니다','/');  
            exit;
        }
        if( $this->session->userdata('logged_in') != TRUE ) 
        {
		alert('로그인 후 이용해 주세요', '/'); exit;
        }
        else
        {
	        //뷰로 부터 넘겨 받은 값
 	        $word_asis_file_name = $_GET['asis'];           
	        $word_tobe_file_name = $_GET['tobe'];
			
			$data = file_get_contents(FCPATH . "uploads/word_file/$word_tobe_file_name");   
			$name = $word_asis_file_name;
			force_download($name, $data); 
	    }
    }

 

 

 다음글 에러로그 문의드립니다!! (5)
 이전글 php 셀레니움 설치 해보신분 있나요?? (1)

댓글

한대승(불의회상) / 2021/01/18 14:28:23 / 추천 0
파일명이 깨진다는게 어떤 의미인가요?
그동안 / 2021/01/18 14:36:18 / 추천 0

아이폰 사파리, pc 맥북 사파리에서 이렇게 됩니다. 참고로 다른 브라우저에서는 문제가 없습니다.

참고로 ie는 아래와 같이 해결했습니니다.

            $filename = iconv('utf-8''euc-kr'$filename);                          //UTF-8에서 euc-kr로 변경
            $header_cachecontrol 'must-revalidate, post-check=0, pre-check=0';
            $header_pragma='public';
한대승(불의회상) / 2021/01/18 17:41:40 / 추천 0
일단 파일명이 utf8이 아닌 euckr로 인코딩되고 있는건 아닌지 부터 확인하셔야 할 것 같습니다.
그동안 / 2021/01/18 21:21:39 / 추천 0

불의화상님, $str_encode = mb_detect_encoding($filename, $encode);

이걸로 확인해본 결과, 컨트롤러를 거쳐, 다운로드 헬퍼의 아랫 부분에 대입되기 전까지는 확실히 UTF-8입니다.

header('Content-Disposition: attachment; filename="'.$filename.'"');

 

한대승(불의회상) / 2021/01/19 09:19:54 / 추천 0

@그동안 올려주신 정보와 코드를 기준으로 문제가 없어 보입니다.

사파리에서 파일명이 깨지는 이유와 해결책을 현재 저의 지식으론 제시하기가 힘들어 보입니다.

도움드리지 못해 아쉽네요.

그동안 / 2021/01/19 09:28:02 / 추천 0

@불의화상님, 댓글 주신 것만으로 감사 드립니다.

근데, 한가지 더 궁금한게, 혹시 서버의 설정만으로 사파리만 이런 현상이 일어날 수 있을까요?

혹시나 서버쪽을 봐야 되는건가 싶어서요.