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

Загрузка файла script не работает при вызове из Ajax

Я использую следующий script для запуска загрузки файлов:

if (file_exists($newfilename)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($newfilename));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate');
    header('Pragma: public');
    header('Content-Length: ' . filesize($newfilename));
    ob_clean();
    flush();
    readfile($newfilename);
    exit;
}

Он отлично работает, когда я открываю страницу напрямую, но дело в том, что мне нужен этот script для вызова через Ajax с другой страницы. Когда я это сделаю, загрузка не начинается. Остальная часть script делает то, что она должна была.

Я предполагаю, что проблема заключается не в возможности использовать функцию заголовка таким образом, но, конечно, есть способ сделать эту работу?

Это функция Ajax, если она имеет любую помощь:

<script type="text/javascript">
    // function create GetXmlHttpObject
    function GetXmlHttpObject()
    {
    if (window.XMLHttpRequest)
    {
    // code for IE7+, Firefox, Chrome, Opera, Safari
    return new XMLHttpRequest();
    }
    if (window.ActiveXObject)
    {
    // code for IE6, IE5
    return new ActiveXObject("Microsoft.XMLHTTP");
    }
    return null;
    }

    function submitVideoAjax(){
    var myAjaxPostrequest=new GetXmlHttpObject();

    var t2_title=document.video_form.title.value;

    var parameters="title="+t2_title;

    myAjaxPostrequest.open("POST", "newdownloadmanager.php", true);
    myAjaxPostrequest.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    myAjaxPostrequest.send(parameters);
    myAjaxPostrequest.onreadystatechange=function(){
    if(myAjaxPostrequest.readyState==4){
    if(myAjaxPostrequest.status==200){
    document.getElementById("result").innerHTML=myAjaxPostrequest.responseText;
    document.getElementById("video_form").style.display = "none";

    }
    else    {
    document.getElementById("video_form").innerHTML="An error has occured making the request";
    }
    }
    }
    }
    </script>

И это форма:

<form name='video_form' id='video_form' method="post">
<input type="hidden" name="title" id="title" value="Madelyn2-01.mp4"/>
<button type="button" name="submit_video" id="submit_video" onclick="submitVideoAjax();">Download</button>
</form>
4b9b3361

Ответ 1

Вы не можете использовать AJAX для загрузки файлов. Это не имеет смысла. Вы можете отправить запрос AJAX и получить содержимое файла внутри обработчика успеха на клиенте, но по очевидным соображениям безопасности вы не можете много сделать с ним. Вы не можете сохранить его на клиентском компьютере, и нет javascript API, позволяющего запрашивать у пользователя, где его сохранить.

Итак, чтобы скачивать файлы, не используйте AJAX. Создайте привязку, указывающую на вашу сторону сервера script, которая служит для загрузки файла.

Ответ 2

javascript не может загружать файлы в качестве проблемы безопасности.

Ответ 3

Запросы AJAX не обслуживают то же самое, что и другой HTTP-запрос браузера. Вам нужно только поместить ссылку на ваш script с нужными параметрами, используя about="_blank" или что-то вроде этого. Современные браузеры хорошо служат.

Ответ 4

Можно загрузить файл с помощью AJAX.

Javascript

function exportToCsv(){

    var xmlhttp;

    if(window.XMLHttpRequest){ xmlhttp = new XMLHttpRequest; }else{ xmlhttp = new ActiveXObject("Microsoft.XMLHTTP"); }
    xmlhttp.onreadystatechange = function(){
        if(xmlhttp.readyState == 4 && xmlhttp.status == 200){
                window.location="download.php?filename=export.csv";
            }

        }
    }
    request = "exportToCsv.php";
    xmlhttp.open("GET", request, true);
    xmlhttp.send();

}

Код выше, экспортирует базу данных mysql из контактов в CSV файл. После этого, если все ОК (xmlhttp.readyState == 4) автоматически запускает загрузку. window.location="download.php?filename=export.csv";

файл download.php:

<?php

    $file = $_GET['filename'];

    header("Cache-Control: public");
    header("Content-Description: File Transfer");
    header("Content-Disposition: attachment; filename=".$file."");
    header("Content-Transfer-Encoding: binary");
    header("Content-Type: binary/octet-stream");
    readfile($file);

?>

После этого браузер просто представляет диалог "Сохранить файл как", и обновление страницы не происходит. У меня есть приложение и работает, и у меня никогда не было проблем. Работает в следующих браузерах:

Chrome v37.0.2062.120 
Firefox v32.0.1
Opera v12.17
Internet Explorer v11

Ответ 5

Когда мне нужно загрузить файл с помощью ajax, у меня есть одна из следующих двух ситуаций:

  • Расширение файла для загрузки интерпретируется веб-сервером (html, txt, pl, php), в зависимости от того, как настроен сервер.
  • Расширение файла - другое, и он содержит физический (или логический) файл, отображаемый в URL-адресе.

В этом втором случае достаточно написать метатег в ответе ajax, записав его в любой элемент innerHTML:

  < meta http-equiv = "refresh" content = "0; URL = 'somedir/worksheet.xls'" />
Код>

Поскольку расширение xls указывает на существующий файл, оно будет немедленно предложено пользователю для загрузки.

В первом случае, однако, невозможно использовать метатег, поскольку расширение является html или любым другим, интерпретируемым веб-сервером, и будет обслуживаться перенаправлением нашего веб-сайта.

Как обычно, предлагать якорь с URL-адресом загружаемого файла для случая, который не запускает загрузку автоматически, я применяю это решение: во-первых, я пишу hiperlink

<Предварительно > <код > < р > Если загрузка не запускается, < a id = "link_id" href= 'somedir/some.html' > нажмите здесь </a> </р > Код >

в какой-то элемент страницы, а затем заставьте функцию обратного вызова нажать на элемент привязки

  document.getElementById( "link_id" ). click();
Код>