Подтвердить что ты не робот

Запросить файл с настраиваемым заголовком

У меня необычное требование. По сути, мне нужен способ, чтобы, когда пользователь нажимает на ссылку или кнопку, они получат PDF файл. Трудная часть здесь заключается в том, что сервер вообще не обрабатывает запрос, если с ним не отправляется настраиваемый заголовок (в противном случае он считает, что человек вышел из системы и отправил его на экран входа в систему).

В настоящий момент способ работы заголовка не может быть изменен, поэтому не останавливайтесь на нем; он будет изменен в будущем и будет внутренним приложением, которое я не контролирую.

Параметры, которые я изучил:

  • Использование iframe или просто открытие нового окна с каким-то путем, который вернет PDF. Это не может работать, потому что я не могу указать требуемый заголовок для PDF и будет перенаправлен до достижения самого PDF.
  • Использование формы и отправка запроса не могут работать, потому что я не могу добавьте произвольные заголовки в формы (только XHR и плагины могут, AFAIK).
  • Использование XHR не может работать, потому что, хотя оно может добавлять заголовок и извлечение файла, сохранить его на стороне клиента нет.

Казалось бы, мои единственные варианты на этом этапе по существу:

  • Для запроса файла используйте какой-то плагин, такой как Flash или Silverlight.
  • Измените требование гораздо раньше, чем ожидалось, чтобы заголовок больше не требовался.

Есть ли что-нибудь, чего я здесь не вижу? Я надеюсь, что кто-то сможет проверить мои результаты или указать на то, что я пропустил, потому что, насколько я могу судить, я ничего не могу сделать здесь.

EDIT: Это кажется подходящим и подтверждает то, что я думал: XMLHttpRequest, чтобы открыть PDF в браузере

4b9b3361

Ответ 1

Протестировано для работы в хроме:

function toBinaryString(data) {
    var ret = [];
    var len = data.length;
    var byte;
    for (var i = 0; i < len; i++) { 
        byte=( data.charCodeAt(i) & 0xFF )>>> 0;
        ret.push( String.fromCharCode(byte) );
    }

    return ret.join('');
}


var xhr = new XMLHttpRequest;

xhr.open( "GET", "/test.pdf" ); //I had test.pdf this on my local server


xhr.addEventListener( "load", function(){
    var data = toBinaryString(this.responseText);
    data = "data:application/pdf;base64,"+btoa(data);
    document.location = data;
}, false);

xhr.setRequestHeader("magic", "header" );
xhr.overrideMimeType( "application/octet-stream; charset=x-user-defined;" );
xhr.send(null);

Вы можете изменить приложение /pdf на приложение/октет-поток, чтобы получить подсказку загрузки. Но это довольно легко загрузить и с хром-ридером.

В firefox ничего не происходит, я предполагаю, потому что у меня нет плагина для установки application/pdf. Переход на приложение/октет-поток вызовет dl.

В IE я предполагаю, что вам нужен какой-то хакерство VBScript/ActiveX

Если файл огромен, использование uri данных может привести к сбою браузера, в этом случае вы можете использовать URL-адреса BlobBuilder и Object.

Ответ 2

Вместо того, чтобы ссылаться на файл .PDF, вместо этого сделайте что-то вроде

<a href="pdf_server.php?file=pdffilename">Download my eBook</a>

который выводит пользовательский заголовок, открывает PDF (двоичный сейф) и печатает данные в пользовательском браузере, тогда они могут выбрать сохранение PDF, несмотря на настройки браузера. Файл pdf_server.php должен выглядеть следующим образом:

header("Content-Type: application/octet-stream");

$file = $_GET["file"] .".pdf";
header("Content-Disposition: attachment; filename=" . urlencode($file));   
header("Content-Type: application/force-download");
header("Content-Type: application/octet-stream");
header("Content-Type: application/download");
header("Content-Description: File Transfer");            
header("Content-Length: " . filesize($file));
flush(); // this doesn't really matter.
$fp = fopen($file, "r");
while (!feof($fp))
{
    echo fread($fp, 65536);
    flush(); // this is essential for large downloads
} 
fclose($fp);

EDIT:. Единственный способ добавить заголовки к запросу из браузера (на стороне клиента) - это XmlHttpRequest setRequestHeader.

xhr.setRequestHeader('custom-header', 'value');