Как загрузить данные из Java-сервера? [Дубликат]

Определение пространств имен в XPath (рекомендуется)

У самого XPath нет способа связать префикс пространства имен с пространством имен. Такие средства предоставляются библиотекой хостинга.

Рекомендуется использовать эти средства и определять префиксы пространства имен, которые затем могут использоваться для квалифицирования XML-элементов и имен атрибутов по мере необходимости.


Вот некоторые из различных механизмов, которые хосты XPath предоставляют для указания привязок префикса пространства имен к URI пространства имен:

XSLT:


   ...

Perl ( LibXML ):

my $xc = XML::LibXML::XPathContext->new($doc);
$xc->registerNs('i', 'http://schema.intuit.com/finance/v3');
my @nodes = $xc->findnodes('/i:IntuitResponse/i:QueryResponse');

Python ( lxml ):

from lxml import etree
f = StringIO('...')
doc = etree.parse(f)
r = doc.xpath('/i:IntuitResponse/i:QueryResponse', 
              namespaces={'i':'http://schema.intuit.com/finance/v3'})

Python ( ElementTree ):

namespaces = {'i': 'http://schema.intuit.com/finance/v3'}
root.findall('/i:IntuitResponse/i:QueryResponse', namespaces)

Java (SAX):

NamespaceSupport support = new NamespaceSupport();
support.pushContext();
support.declarePrefix("i", "http://schema.intuit.com/finance/v3");

Java (XPath):

xpath.setNamespaceContext(new NamespaceContext() {
    public String getNamespaceURI(String prefix) {
      switch (prefix) {
        case "i": return "http://schema.intuit.com/finance/v3";
        // ...
       }
    });

C #:

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("i", "http://schema.intuit.com/finance/v3");
XmlNodeList nodes = el.SelectNodes(@"/i:IntuitResponse/i:QueryResponse", nsmgr);

xmlstarlet:

-N i="http://schema.intuit.com/finance/v3"

JavaScript:

См. Реализация разрешенного пользователем пространства имен Resolver :

function nsResolver(prefix) {
  var ns = {
    'i' : 'http://schema.intuit.com/finance/v3'
  };
  return ns[prefix] || null;
}
document.evaluate( '/i:IntuitResponse/i:QueryResponse', 
                   document, nsResolver, XPathResult.ANY_TYPE, 
                   null );

PhP :

Адаптировано из @ ответа Томалака с использованием DOMDocument :

$result = new DOMDocument();
$result->loadXML($xml);

$xpath = new DOMXpath($result);
$xpath->registerNamespace("i", "http://schema.intuit.com/finance/v3");

$result = $xpath->query("/i:IntuitResponse/i:QueryResponse");

См. также @ Канонический Q / A IMSoP на PHP Пространства имен SimpleXML .

VBA:

xmlNS = "xmlns:i='http://schema.intuit.com/finance/v3'"
doc.setProperty "SelectionNamespaces", xmlNS  
Set queryResponseElement =doc.SelectSingleNode("/i:IntuitResponse/i:QueryResponse")

Как только вы объявили префикс пространства имен, ваш XPath можно записать, чтобы использовать его:

/i:IntuitResponse/i:QueryResponse

Поражение пространств имен в XPath (не рекомендуется)

Альтернативой является запись предикатов, которые проверяют на local-name():

/*[local-name()='IntuitResponse']/*[local-name()='QueryResponse']/@startPosition

Или, в XPath 2.0:

/*:IntuitResponse/*:QueryResponse/@startPosition

Пространство имен в этом стиле работает, но не рекомендуется, потому что оно

  • Под-указывает полное имя элемента / атрибута.
  • Не удается различать имена элементов / атрибутов в разных пространствах имен (сама цель пространств имен). Обратите внимание, что эту проблему можно решить, добавив дополнительный предикат, чтобы проверить URI пространства имен явно1:
    /*[    namespace-uri()='http://schema.intuit.com/finance/v3' 
       and local-name()='IntuitResponse']
    /*[    namespace-uri()='http://schema.intuit.com/finance/v3' 
       and local-name()='QueryResponse']
    /@startPosition
    
    1Подается Даниэль Хейли для примечания namespace-uri().
  • Является чрезмерно подробным .
342
задан Cœur 28 December 2016 в 14:48
поделиться

15 ответов

590
ответ дан Community 6 September 2018 в 14:12
поделиться
595
ответ дан Community 29 October 2018 в 20:34
поделиться

В Rails я делаю так:

function download_file(file_id) {
  let url       = '/files/' + file_id + '/download_file';
    $.ajax({
    type: 'GET',
    url: url,
    processData: false,
    success: function (data) {
       window.location = url;
    },
    error: function (xhr) {
     console.log(' Error:  >>>> ' + JSON.stringify(xhr));
    }
   });
 }

Трюк - это часть window.location . Метод контроллера выглядит так:

# GET /files/{:id}/download_file/
def download_file
    send_file(@file.file,
          :disposition => 'attachment',
          :url_based_filename => false)
end
1
ответ дан aarkerio 17 August 2018 в 22:11
поделиться
  • 1
    Быстрый вопрос, не будет ли это генерировать файл дважды? После отправки запроса ajax. Затем вы перенаправляете страницу на тот же URL-адрес. Как мы можем это устранить? – coderhs 4 June 2018 в 06:23
  • 2
    Не в моем случае. Я тестировал его только на Chrome. – aarkerio 4 June 2018 в 15:31
  • 3
    Поскольку coderhs уже корректно заявляет, действие вызывается дважды. – Sven 15 June 2018 в 10:29

Вот что я сделал, чистый javascript и html. Не тестировал, но это должно работать во всех браузерах.

Функция Javascript

var iframe = document.createElement('iframe');
iframe.id = "IFRAMEID";
iframe.style.display = 'none';
document.body.appendChild(iframe);
iframe.src = 'SERVERURL'+'?' + $.param($scope.filtro);
iframe.addEventListener("load", function () {
     console.log("FILE LOAD DONE.. Download should start now");
});

Использование только компонентов, поддерживаемых во всех браузерах нет дополнительных библиотек.

enter image description here [/g0] enter image description here [/g1]

Вот код контроллера JAVA Spring на стороне сервера.

@RequestMapping(value = "/rootto/my/xlsx", method = RequestMethod.GET)
public void downloadExcelFile(@RequestParam(value = "param1", required = false) String param1,
    HttpServletRequest request, HttpServletResponse response)
            throws ParseException {

    Workbook wb = service.getWorkbook(param1);
    if (wb != null) {
        try {
            String fileName = "myfile_" + sdf.format(new Date());
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-disposition", "attachment; filename=\"" + fileName + ".xlsx\"");
            wb.write(response.getOutputStream());
            response.getOutputStream().close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    }
6
ответ дан alexbt 17 August 2018 в 22:11
поделиться
  • 1
    кажется, что ваше событие загрузки не вызвано для содержимого вложения содержимого (поскольку ничего не загружено в iframe), если он работает для вас (вы получаете консоль.log), pls отправляет образец – kofifus 30 June 2015 в 06:33
  • 2
    Вот быстрый скрипт jsfiddle.net/y2xezyoj , который вскоре запускает событие загрузки, когда файл pdf загружается в iframe .. эта скрипка не загружается, потому что ключ для загрузки находится на стороне сервера & quot; response.setHeader ("Content-disposition", " attachment ; filename = \ & quot; + fileName +" .xlsx \ & quot; "); & quot; – manukyanv07 30 June 2015 в 19:13
  • 3
    да, он будет работать в этом случае, но если файл будет загружен, то сервер отправит Content-Disposition: attachment, тогда событие загрузки не будет срабатывать, что было моей точкой – kofifus 30 June 2015 в 23:38
  • 4
    Вы полностью правильно загружаете событие, запущенное сразу после того, как сервер завершил обработку, начинает отправку файла. Это то, что я искал, 1- блокировать кнопку и отображать обработку, чтобы пользователь мог получить обратную связь о том, что происходит. 2 - Затем, когда сервер завершает обработку и собирается отправить файл 3 (событие загрузки запускается), где я разблокирую кнопку и удаляю обработку spinner 4 - пользователь теперь отображается с сохраненным файлом или браузер начинает загружать его в определенное местоположение загрузки. Извините мой английский. – manukyanv07 2 July 2015 в 21:45

Если вы хотите использовать загрузку файла jQuery, обратите внимание на это для IE. Вам нужно сбросить ответ или он не будет загружен

    //The IE will only work if you reset response
    getServletResponse().reset();
    //The jquery.fileDownload needs a cookie be set
    getServletResponse().setHeader("Set-Cookie", "fileDownload=true; path=/");
    //Do the reset of your action create InputStream and return

. Ваше действие может реализовать ServletResponseAware для доступа к getServletResponse()

0
ответ дан Alireza Fattahi 17 August 2018 в 22:11
поделиться

Уверен, что вы не можете сделать это через вызов Ajax.

Однако существует обходное решение.

Шаги:

Если вы используете form.submit () для загрузки файла, что вы можете сделать:

  1. Создайте ajax-вызов от клиента к серверу и сохраните поток файлов внутри сеанса.
  2. После «успеха», возвращаемого с сервера, вызовите форму .submit (), чтобы просто передать поток файлов, хранящийся в сеансе.

Это полезно в том случае, если вы хотите решить, не нужно загружать файл после создания form.submit (), например: может быть случай, когда в form.submit () исключение возникает на стороне сервера и вместо сбоя может потребоваться показать пользовательское сообщение на клиентская сторона, в этом случае эта реализация может помочь.

0
ответ дан Aman Srivastava 17 August 2018 в 22:11
поделиться

Добавляем еще несколько вещей для ответа на этот вопрос для загрузки файла

Ниже приведен код java spring, который генерирует байт Array

@RequestMapping(value = "/downloadReport", method = { RequestMethod.POST })
    public ResponseEntity<byte[]> downloadReport(
            @RequestBody final SomeObejct obj, HttpServletResponse response) throws Exception {

        OutputStream out = new ByteArrayOutputStream();
        // write something to output stream
        HttpHeaders respHeaders = new HttpHeaders();
        respHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        respHeaders.add("X-File-Name", name);
        ByteArrayOutputStream bos = (ByteArrayOutputStream) out;
        return new ResponseEntity<byte[]>(bos.toByteArray(), respHeaders, HttpStatus.CREATED);
    }

Теперь в javascript-коде с использованием FileSaver.js, можно загрузить файл с кодом ниже

var json=angular.toJson("somejsobject");
var url=apiEndPoint+'some url';
var xhr = new XMLHttpRequest();
//headers('X-File-Name')
xhr.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 201) {
        var res = this.response;
        var fileName=this.getResponseHeader('X-File-Name');
        var data = new Blob([res]);
        saveAs(data, fileName); //this from FileSaver.js
    }
}    
xhr.open('POST', url);
xhr.setRequestHeader('Authorization','Bearer ' + token);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.responseType = 'arraybuffer';
xhr.send(json);

Вышеупомянутый файл будет загружен

3
ответ дан cheb1k4 17 August 2018 в 22:11
поделиться

Никто не отправил это @ решение Пекки ... поэтому я опубликую его. Это может помочь кому-то.

Вы не можете и не должны делать это через Ajax. Просто используйте

window.location="download.action?para1=value1...."
178
ответ дан Community 17 August 2018 в 22:11
поделиться
  • 1
    Мне нравится то, что вы построили, но я подозреваю, что для получения дополнительной информации о StackOverFlow ваш ответ здесь должен содержать немного более подробную информацию. В частности, как вы решили проблему. – AnthonyVO 7 August 2012 в 22:58
  • 2
    Хороший ... поскольку я боролся с обработкой подсказки файла загрузки и использованием jquery ajax..and это решение отлично работает для меня .. + 1 – swapnesh 1 March 2013 в 10:49
  • 3
    Обратите внимание, что для этого требуется, чтобы сервер устанавливал значение заголовка Content-Disposition для «вложения», иначе браузер будет перенаправлять (и отображать) контент ответа – brichins 24 April 2013 в 22:45
  • 4
    было бы неплохо, если бы вы точно указали, как этот «плагин» обойти ограничения, а не заставлять нас заходить в ваш блог / источник плагина, чтобы увидеть его. например, вместо этого он отправляется в iframe? вместо этого требуется, чтобы удаленный скрипт сохранил файл и вернул ему URL-адрес? – Kevin B 23 September 2013 в 20:47
  • 5
    Я согласен с тем, что блог - это гораздо лучшее место, где можно найти подробное описание того, как использовать плагин и как он работает. но вы могли бы хотя бы дать краткий обзор того, как этот плагин решает проблему. Например, это решает проблему, если сервер установит cookie и ваш javascript постоянно ищет cookie до тех пор, пока он не будет существовать. Как только он существует, мы можем предположить, что загрузка завершена. С помощью такой информации можно быстро свернуть свое решение очень быстро, и ответ больше не зависит от вашего блога / плагина / jquery на 100% и может быть применен к другим библиотекам. – Kevin B 30 October 2013 в 22:10
  • 6
    Royi, так как я понимаю, что AJAX может никогда поддерживать загрузку файлов, что приводит к всплыванию файла для сохранения на диск. Вы нашли способ, о котором я не знаю? – John Culviner 13 January 2014 в 18:19
  • 7
    Или, альтернативно, используйте window.open(<url>, '_blank');, чтобы гарантировать, что загрузка не заменит ваш текущий контент браузера (независимо от заголовка Content-Disposition). – Christopher King 15 August 2014 в 16:38
  • 8
    это хорошее решение, но я хочу показать загрузочный бар при загрузке. и это невозможно с тем же механизмом. – Yogesh Prajapati 26 August 2014 в 05:56
  • 9
    Сэр, ваш вход: & quot; Content-Disposition & quot ;, inline; .... сохранен день плохого кодера :) – Vedran Maricevic. 29 May 2015 в 14:23
  • 10
    Проблема с этим решением заключается в том, что если операция завершается неудачно / сервер возвращает ошибку, ваша страница будет перенаправлена ​​на страницу с ошибкой. Чтобы решить эту проблему, используйте решение iFrame – kofifus 30 June 2015 в 23:52
  • 11
    @StanE спасибо за комментарий. Я обновил нижнюю часть своего ответа, в котором уточняются некоторые варианты теперь, когда это 2016 год (и jQuery был почти верным, когда я написал этот плагин и ответил на этот вопрос, что, конечно же, не так) – John Culviner 27 September 2016 в 16:28
  • 12
    a.click(), похоже, не работает в firefox ... Любая идея? – ssostalker 14 November 2017 в 19:34
  • 13
    В некоторых браузерах вам может потребоваться добавить a в dom, чтобы этот код работал и / или удалял часть revokeObjectURL: document.body.appendChild(a) – ssostalker 14 November 2017 в 22:26
  • 14
    Ты спас мой день! :) ;) Спасибо ! :) – Merianos Nikos 30 May 2018 в 09:21

Простой способ заставить браузер загружать файл - это сделать такой запрос:

 function downloadFile(urlToSend) {
     var req = new XMLHttpRequest();
     req.open("GET", urlToSend, true);
     req.responseType = "blob";
     req.onload = function (event) {
         var blob = req.response;
         var fileName = req.getResponseHeader("fileName") //if you have the fileName header available
         var link=document.createElement('a');
         link.href=window.URL.createObjectURL(blob);
         link.download=fileName;
         link.click();
     };

     req.send();
 }

Это открывает всплывающее окно браузера.

6
ответ дан João Marcos 17 August 2018 в 22:11
поделиться
  • 1
    Спасибо, я использовал это решение. Работал как шарм. Кроме того, если вы не получите blob от ответа, просто создайте новый Blob. – fabio.sang 3 October 2017 в 07:22
  • 2
    Лучшая версия с обработкой IE link – startsWith_R 7 June 2018 в 08:03

Я нашел исправление, что, хотя на самом деле он не использует ajax, он позволяет вам использовать вызов javascript для запроса загрузки, а затем получить обратный вызов, когда загрузка начнется. Я нашел это полезным, если ссылка запускает скрипт на стороне сервера, который занимает немного времени, чтобы составить файл перед его отправкой. поэтому вы можете предупредить их о том, что он обрабатывается, а затем, когда он наконец отправит файл, удалите это уведомление об обработке. поэтому я хотел попытаться загрузить файл через ajax, чтобы начать с того, что я мог бы иметь событие, когда файл запрашивается, а другой, когда он действительно начинает загружаться.

js на первой странице

function expdone()
{
    document.getElementById('exportdiv').style.display='none';
}
function expgo()
{
   document.getElementById('exportdiv').style.display='block';
   document.getElementById('exportif').src='test2.php?arguments=data';
}

iframe

<div id="exportdiv" style="display:none;">
<img src="loader.gif"><br><h1>Generating Report</h1>
<iframe id="exportif" src="" style="width: 1px;height: 1px; border:0px;"></iframe>
</div>

, а затем другой файл:

<!DOCTYPE html>
<html>
<head>
<script>
function expdone()
{
    window.parent.expdone();
}
</script>
</head>
<body>
<iframe id="exportif" src="<?php echo "http://10.192.37.211/npdtracker/exportthismonth.php?arguments=".$_GET["arguments"]; ?>"></iframe>
<script>document.getElementById('exportif').onload= expdone;</script>
</body></html>

Я думаю, что есть способ прочитать данные с помощью js, чтобы потом php не понадобится. но я не знаю, это от руки, а сервер, который я использую, поддерживает php, поэтому это работает для меня. подумал, что я поделюсь им, если он кому-то поможет.

0
ответ дан Kit Ramos 17 August 2018 в 22:11
поделиться

Я столкнулся с той же проблемой и успешно ее разрешил.

«Опубликовать данные JSON на сервере и получить файл excel. Этот файл excel создается сервером и возвращается как ответ клиенту. Загрузите этот ответ в виде файла с пользовательским именем в браузере "

$("#my-button").on("click", function(){

// Data to post
data = {
    ids: [1, 2, 3, 4, 5]
};

// Use XMLHttpRequest instead of Jquery $ajax
xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
    var a;
    if (xhttp.readyState === 4 && xhttp.status === 200) {
        // Trick for making downloadable link
        a = document.createElement('a');
        a.href = window.URL.createObjectURL(xhttp.response);
        // Give filename you wish to download
        a.download = "test-file.xls";
        a.style.display = 'none';
        document.body.appendChild(a);
        a.click();
    }
};
// Post data to URL which handles post request
xhttp.open("POST", excelDownloadUrl);
xhttp.setRequestHeader("Content-Type", "application/json");
// You should set responseType as blob for binary responses
xhttp.responseType = 'blob';
xhttp.send(JSON.stringify(data));
});

Вышеприведенный фрагмент просто выполняет следующие действия

  • Проводка массива как JSON на сервер с использованием XMLHttpRequest.
  • После извлечения содержимого в виде blob (двоичного) мы создаем загружаемый URL-адрес и привязываем его к невидимой ссылке «a», а затем щелкаем по ней. Я сделал запрос POST здесь. Вместо этого вы можете пойти и для простого GET. Мы не можем загрузить файл через Ajax, должны использовать XMLHttpRequest.

Здесь нам нужно тщательно установить несколько вещей на стороне сервера. Я установил несколько заголовков в Python Django HttpResponse. Вы должны установить их соответственно, если используете другие языки программирования.

# In python django code
response = HttpResponse(file_content, content_type="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")

Так как я загружаю xls (excel) здесь, я скорректировал contentType на один. Вам нужно установить его в соответствии с типом файла. Вы можете использовать эту технику для загрузки любых файлов.

11
ответ дан Naren Yellavula 17 August 2018 в 22:11
поделиться

Я создал небольшую функцию в качестве решения обхода (вдохновленный плагином @JohnCulviner):

// creates iframe and form in it with hidden field,
// then submit form with provided data
// url - form url
// data - data to form field
// input_name - form hidden input name

function ajax_download(url, data, input_name) {
    var $iframe,
        iframe_doc,
        iframe_html;

    if (($iframe = $('#download_iframe')).length === 0) {
        $iframe = $("<iframe id='download_iframe'" +
                    " style='display: none' src='about:blank'></iframe>"
                   ).appendTo("body");
    }

    iframe_doc = $iframe[0].contentWindow || $iframe[0].contentDocument;
    if (iframe_doc.document) {
        iframe_doc = iframe_doc.document;
    }

    iframe_html = "<html><head></head><body><form method='POST' action='" +
                  url +"'>" +
                  "<input type=hidden name='" + input_name + "' value='" +
                  JSON.stringify(data) +"'/></form>" +
                  "</body></html>";

    iframe_doc.open();
    iframe_doc.write(iframe_html);
    $(iframe_doc).find('form').submit();
}

Демо с событием click:

$('#someid').on('click', function() {
    ajax_download('/download.action', {'para1': 1, 'para2': 2}, 'dataname');
});
21
ответ дан ndpu 17 August 2018 в 22:11
поделиться
  • 1
    Тем не менее, это посылает данные на very странном пути к серверу. Интересно, может ли он быть изменен для создания совместимого POST? – Shayne 19 January 2014 в 23:44
  • 2
    @Shayne это могло, но это работает нормально для меня с json – ndpu 20 January 2014 в 09:50
  • 3
    Это было лучшим решением для моей ситуации. почет – Rob10e 21 November 2017 в 19:59

Хорошо, на основе кода ndpu, это улучшенная (я думаю) версия ajax_download; -

function ajax_download(url, data) {
    var $iframe,
        iframe_doc,
        iframe_html;

    if (($iframe = $('#download_iframe')).length === 0) {
        $iframe = $("<iframe id='download_iframe'" +
                    " style='display: none' src='about:blank'></iframe>"
                   ).appendTo("body");
    }

    iframe_doc = $iframe[0].contentWindow || $iframe[0].contentDocument;
    if (iframe_doc.document) {
        iframe_doc = iframe_doc.document;
    }

    iframe_html = "<html><head></head><body><form method='POST' action='" +
                  url +"'>" 

    Object.keys(data).forEach(function(key){
        iframe_html += "<input type='hidden' name='"+key+"' value='"+data[key]+"'>";

    });

        iframe_html +="</form></body></html>";

    iframe_doc.open();
    iframe_doc.write(iframe_html);
    $(iframe_doc).find('form').submit();
}

Используйте это следующим образом: -

$('#someid').on('click', function() {
    ajax_download('/download.action', {'para1': 1, 'para2': 2});
});

Параметры отправлены как правильные пост-параметры, как если бы они поступали из ввода, а не как json-кодированная строка в соответствии с предыдущим примером.

CAVEAT: Будьте осторожны в отношении возможности для переменной инъекции в этих формах. Может быть более безопасный способ кодирования этих переменных. Альтернативно созерцайте их.

15
ответ дан Shayne 17 August 2018 в 22:11
поделиться
  • 1
    Это рабочий пример. Благодарю. Можно ли сделать это без iframe, но без window.location? – Marek Bar 15 October 2014 в 14:57
  • 2
    Полагаю, вы могли бы просто добавить скрытую форму к нижней части DOM. Также, возможно, стоит изучить использование Shadow dom, хотя это не обязательно хорошо поддерживается в старых браузерах. – Shayne 17 October 2014 в 03:44
  • 3
    В этом коде я получаю эту ошибку. Uncaught SecurityError: Blocked a frame with origin "http://foo.bar.com" from accessing a frame with origin "null". The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "data". Protocols must match. – void 16 January 2016 в 11:09
  • 4
    Как я могу сопоставить эту форму с некоторым классом модели? У меня есть: @ResourceMapping() public void downloadFile(final ResourceRequest request, final ResourceResponse response, @ModelAttribute("downForm") FormModel model), но он не работает. – bartex9 12 January 2017 в 10:23
  • 5
    void: Вероятно, это будет какая-то проблема безопасности скреста. Это, вероятно, целый вопрос о переполнении стека и сам. @ bartex9: Это будет сильно зависеть от того, какую структуру вы используете. Но принцип должен состоять в том, чтобы взять имя и путь и сохранить это, одновременно нажав файл в веб-доступную область файловой системы или что-то вроде amazon S3 для высокой доступности – Shayne 13 January 2017 в 03:23
function downloadURI(uri, name) 
{
    var link = document.createElement("a");
    link.download = name;
    link.href = uri;
    link.click();
}
3
ответ дан Wai Ha Lee 17 August 2018 в 22:11
поделиться
  • 1
    Не могли бы вы объяснить свой ответ? Это поможет другим понять, что вы сделали, чтобы они могли применять ваши методы к их ситуациям. – Wai Ha Lee 12 April 2016 в 16:34
  • 2
    Просто предупреждение: Safari и IE не поддерживают атрибут download, поэтому ваш файл будет иметь имя & quot; Неизвестно & quot; – Yangshun Tay 16 May 2016 в 09:21

Итак, вот рабочий код при использовании MVC, и вы получаете свой файл с контроллера

, предположим, что ваш массив байтов объявляется и заполняется, единственное, что вам нужно сделать, это использовать функцию File (используя System.Web.Mvc)

byte[] bytes = .... insert your bytes in the array
return File(bytes, System.Net.Mime.MediaTypeNames.Application.Octet, "nameoffile.exe");

, а затем в том же контроллере добавьте thoses 2 функции

protected override void OnResultExecuting(ResultExecutingContext context)
    {
        CheckAndHandleFileResult(context);

        base.OnResultExecuting(context);
    }

    private const string FILE_DOWNLOAD_COOKIE_NAME = "fileDownload";

    /// <summary>
    /// If the current response is a FileResult (an MVC base class for files) then write a
    /// cookie to inform jquery.fileDownload that a successful file download has occured
    /// </summary>
    /// <param name="context"></param>
    private void CheckAndHandleFileResult(ResultExecutingContext context)
    {
        if (context.Result is FileResult)
            //jquery.fileDownload uses this cookie to determine that a file download has completed successfully
            Response.SetCookie(new HttpCookie(FILE_DOWNLOAD_COOKIE_NAME, "true") { Path = "/" });
        else
            //ensure that the cookie is removed in case someone did a file download without using jquery.fileDownload
            if (Request.Cookies[FILE_DOWNLOAD_COOKIE_NAME] != null)
                Response.Cookies[FILE_DOWNLOAD_COOKIE_NAME].Expires = DateTime.Now.AddYears(-1);
    }

, после чего вы сможете вызовите своего контроллера для загрузки и получите обратный вызов «успех» или «отказ»

$.fileDownload(mvcUrl('name of the controller'), {
            httpMethod: 'POST',
            successCallback: function (url) {
            //insert success code

            },
            failCallback: function (html, url) {
            //insert fail code
            }
        });
1
ответ дан Yannick Richard 17 August 2018 в 22:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: