2013-05-28 5 views
13

У меня есть следующий код, чтобы загрузить файл .csv:Использование JQuery и IFrame для загрузки файла

 $.ajax({ 
      url: urlString, 
      contentType: "application/json; charset=utf-8", 
      dataType: "json", 
      cache: false, 
      success: function (data) { 
       if (data) { 
        var iframe = $("<iframe/>").attr({ 
         src: data, 
         style: "visibility:hidden;display:none" 
        }).appendTo(buttonToDownloadFile); 
       } else { 
        alert('Something went wrong'); 
       } 
      } 
     }); 

urlString указывает на RESTful сервис, который генерирует файл в формате CSV и возвращает путь к файлу, который присваивается атрибуту src для iFrame. Это работает для любых CSV-файлов, но у меня проблемы с XML-файлами. Когда я использую тот же код, но изменяя contentType на «text/xml» и использую его для загрузки XML-файлов, это не работает.

Могу ли я использовать тот же подход для файлов .xml?

UPDATE:

Благодаря Бен для указал мне в правильном направлении. Оказывается, мне вообще не нужен звонок ajax. Вместо этого я могу просто использовать iFrame и его атрибут url для вызова веб-службы, которая будет генерировать контент, добавить заголовок (Content-Disposition) и вернуть поток.

ответ

11

Я предполагаю, что проблема заключается в том, что большинство браузеров попытаются отобразить XML в самом браузере, тогда как у них, как правило, нет обработчика для CSV, поэтому они автоматически по умолчанию запрашивают у пользователя загрузку файла. Попробуйте изменить заголовки XML-файла, чтобы принудительно загрузить. Нечто подобное (PHP пример):

header("Content-Type: application/force-download"); 
header("Content-Type: application/octet-stream"); 
header("Content-Type: application/download"); 
header('Content-Disposition: attachment; filename="some filename"'); 

Это должно сказать большинство браузеров не пытаться открыть файл, но вместо того, чтобы пользователь загрузить файл и пусть OS определить, что с ним делать.

Если у вас нет полномочий для управления заголовками в самом файле XML, вы можете попробовать обход, используя серверный скрипт. Используйте JS передать URL на стороне сервера сценария:

//build the new URL 
var my_url = 'http://mysite.com/load_file_script?url='+escape(path_to_file); 
//load it into a hidden iframe 
var iframe = $("<iframe/>").attr({ 
         src: my_url, 
         style: "visibility:hidden;display:none" 
        }).appendTo(buttonToDownloadFile); 

и на стороне сервера (ваш http://mysite.com/load_file_script скрипт) используется cURL/file_get_contents/wgets/[какой-либо другой механизм извлечения удаленных файлов], чтобы захватить содержимое удаленного файла, добавить заголовки Content-Disposition: attachment и print код оригинального файла.

+0

Боюсь, я не совсем понимаю работу - предложил ты. Мой сервер - .NET (WCF). Вы хотите сказать, что я должен добавлять заголовки со стороны сервера? – notlkk

+0

Да. Если вы не контролируете RESTful API, то вы не можете установить заголовки, используя только HTML/JS. Итак, что вы делаете, это создать скрипт на вашем сервере .NET, который может получить удаленный URL-адрес в качестве аргумента, забрать удаленный файл, повторно упаковать его с новыми заголовками и затем выполнить его как вложение. –

+0

Я вижу. Нужно ли мне все 4 заголовка, как вы указали? И какой тип содержимого я должен использовать в своем javascript? – notlkk

16

Вы также можете предложить его в качестве загрузки с виртуального элемента анкера, даже если данные на стороне клиента:

/* 
* Create an anchor to some inline data... 
*/ 

var url = 'data:application/octet-stream,Testing%20one%20two%20three'; 
var anchor = document.createElement('a'); 
    anchor.setAttribute('href', url); 
    anchor.setAttribute('download', 'myNote.txt'); 

/* 
* Click the anchor 
*/ 

// Chrome can do anchor.click(), but let's do something that Firefox can handle too 

// Create event 
var ev = document.createEvent("MouseEvents"); 
    ev.initMouseEvent("click", true, false, self, 0, 0, 0, 0, 0, false, false, false, false, 0, null); 

// Fire event 
anchor.dispatchEvent(ev); 

http://jsfiddle.net/D572L/

+2

Блестящий. Это только помогло мне с дилеммой (вывод сгенерированного PDF с использованием $ .ajax, чтобы вы могли отображать загрузчик при нажатии ссылки для загрузки, а затем скрывать его снова, как только файл предлагается браузеру. Спасибо! –

+1

Спасибо! Он работает на ios в противоположность скрытому iframe. – Lucas

+0

Awesome! Спасибо. –

Смежные вопросы