User-Agent 분기 없이 일본어 파일 이름으로 파일 다운로드(이론 편)
10230 단어 PHP
Content-Disposition
를 통해 헤더filename
의 형식과 문자 코드를 바꾸는 방법1을 알게 되었습니다. 이번에는 User-Agent에 의존하지 않고 브라우저를 교차시켜 일본어 파일 이름을 다운로드하는 방법을 소개하고 싶습니다.개요
Content-Disposition
를 통해 헤더를 보내지 않음브라우저에서 파일을 저장할 때 무엇을 참고하시겠습니까?
브라우저가 웹 페이지의 자원을 로컬로 저장할 때 반드시 파일 이름을 추가해야 하는데, 브라우저는 도대체 무엇을 참고하여 파일 이름을 결정합니까?
먼저 HTML
<title>
태그의 문자열 + 를 고려합니다.예)둘째, 이미지 파일이 URL에 포함된 파일 이름인 HTML이 아닌 경우
마지막으로
Content-Disposition
헤더filename
의 값입니다.아마도 다른 것이 있을 것이다. 대체로 이 세 가지 중의 하나일 것이다.
두 번째 파일 이름을 결정하는 방법에 착안하고 싶습니다.위의 예에서 영어의 파일 이름은 Web-browser이다usage_on_Wikimedia.svg이지만 URL에서 URL 인코딩만 하면 일본어를 포함할 수 있기 때문에 일본어 파일 이름을 URL 경로에 포함시키고 싶습니다.
$_SERVER를 이용해서 ['PATH INFO']
PHP의 경우 PHP 파일 이름 뒤에 사선을 더하면 쿼리 열 앞에 있는 경로가
$_SERVER['PATH_INFO']
에 저장됩니다.예를 들어 방문
http://example.com/index.php/foo/bar/buz?hoge=123
의 경우 index.php 설정$_SERVER['PATH_INFO'] = '/foo/bar/buz'
.이 방법을 활용하면
PATH_INFO
에 다운로드용 파일 이름을 설정하면 된다.예를 들어 index.php/請求書-2016年02月-1432.pdf?invoice_id=1432
와 같은 URL로 PDF를 생성하면 브라우저는 PDF를 請求書-2016年02月-1432.pdf
로 저장합니다.서버측 index입니다.php는
PATH_INFO
의 값을 무시할 수 있지만 URL은 사용자가 결정하기 때문에 파일 이름을 함부로 붙이지 않으려면 $_GET['invoice_id']
를 키로 요청한 데이터에 비해 개발자가 의도한 파일 이름과 동일한지 검사할 수 있다PATH_INFO
.샘플 코드: 일본어 파일 이름으로 저장된 예
다음 샘플 코드는 웹 페이지의 자원을 임의의 파일 이름으로 저장하는 예입니다.볼 수 있지만 User-Agent 분기가 없습니다.
download.php
$filename = isset($_SERVER['PATH_INFO']) ? trim($_SERVER['PATH_INFO'], '/') : '';
$file = isset($_GET['file']) ? $_GET['file'] : '';
if (empty($filename) or empty($file)) {
header('HTTP', null, 400);
header('Content-Type: text/plain');
die('Invalid request');
}
// ファイルの内容をとってくる処理
$contents = @file_get_contents("http://$file"); // ここはもう少し安全にする必要があるがサンプルなので割愛
if ($contents === false) {
header('HTTP', null, 500);
header('Content-Type: text/plain');
die(error_get_last()['message']);
}
// ファイルをダウンロードさせる処理
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment');
header('Content-Length: ' . strlen($contents));
echo $contents;
이 샘플의 사용 방법에 대해 사용자는 http://example.com/download.php/[ファイル名]?file=[リソース名]
등 URL에 접근해서 사용할 수 있다.파일 이름은 다운로드할 때의 파일 이름을 지정하고, 자원 이름은 URL에서 프로토콜을 제외하는 부분을 지정합니다.2 예를 들어 Qita의Mardown 메모 태그 Mardown 파일을 다운로드하려면 다음 URL을 방문하십시오.
http://example.com/download.php/Markdown%E8%A8%98%E6%B3%95%20%E3%83%81%E3%83%BC%E3%83%88%E3%82%B7%E3%83%BC%E3%83%88.md?file=qiita.com/Qiita/items/c686397e4a0f4f11683d.md
^ この部分がダウンロード向けファイル名
이 URL에 액세스했습니다. 브라우저의 동작은 다음과 같습니다.Google Chrome은 의도한 파일 이름으로 문제없이 저장됩니다.
Firefox도 괜찮을 것 같아요.
사파리도 괜찮아.
우려되는 IE11도 문제가 없는 것으로 보인다.
URL 인코딩 고려 사항
URL에 일본어 파일 이름을 포함하려면 URL 인코딩이 필요하지만 인코딩할 함수는 사용
rawurlencode
입니다.urlencode
함수를 사용하면 반각 공간+
이 인코딩되지만 파일 이름은 직접 표시+
됩니다.라우터를 사용하면 URL이 더 선명해집니다.
이번에 소개된 샘플 코드는 쿼리 열에서 파일 자원을 찾는 것으로, MVC 프레임워크의 라우터를 사용하면 URL이 더욱 뚜렷해진다.
예를 들어, Silex에서 다음 라우트를 설정한 경우
/invoices/1432/請求書-2016年02月-1432.pdf
등의 URL을 통해 파일을 다운로드할 수 있습니다.$app = new Silex\Application();
$app->get('/invoices/{invoiceId}/{filename}', function($invoiceId, $filename) use($app) {
// ここで $invoiceId から請求データを取得し、PDFを出力する
})->assert('filename', '.+\.pdf');
$app->run();
끝맺다
이번에는 User-Agent에서 분기되지 않는 일본어 파일 이름을 다운로드하는 방법에 대해 설명합니다.검증된 브라우저가 많지 않기 때문에 정상적으로 실행되지 않는 브라우저를 보고할 수 있다면 다행입니다.
계속: User-Agent 분기 없이 일본어 파일 이름으로 파일 다운로드(전체 버전)
[일본어 파일 이름에 해당] 파일을 간단하게 다운로드하는 함수 - Qita ↩
이 코드는 단지 일본어 URL을 간단하게 테스트하기 위해서이며, '파일 내용 추출 처리' 부분은 어떤 URL에서도 얻을 수 있지만, 실제로는 더욱 구속적인 설치가 더욱 안전하다.실천적인 실현은 @mpyw선생님의 User-Agent 분기 없이 일본어 파일 이름으로 파일 다운로드(전체 버전)을 보십시오. ↩
Reference
이 문제에 관하여(User-Agent 분기 없이 일본어 파일 이름으로 파일 다운로드(이론 편)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/suin/items/d1fc9e1ae3e255ae3b37텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)